| @@ -1,5 +1,8 @@ | |||
| [run] | |||
| init_cmds = [["./gogs", "web"]] | |||
| init_cmds = [ | |||
| ["grep", "-rn", "FIXME", "."], | |||
| ["./gogs", "web"] | |||
| ] | |||
| watch_all = true | |||
| watch_dirs = [ | |||
| "$WORKDIR/conf/locale", | |||
| @@ -11,7 +14,7 @@ watch_dirs = [ | |||
| watch_exts = [".go", ".ini"] | |||
| build_delay = 1500 | |||
| cmds = [ | |||
| ["go", "install"], | |||
| ["go", "build"], | |||
| ["go", "install", "-tags", "sqlite cert"], | |||
| ["go", "build", "-tags", "sqlite cert"], | |||
| ["./gogs", "web"] | |||
| ] | |||
| @@ -16,6 +16,6 @@ settings: | |||
| then | |||
| go install -v | |||
| else | |||
| go get -v -tags "sqlite redis memecache" github.com/gogits/gogs | |||
| go install -v -tags "sqlite redis memecache" | |||
| go get -v -tags "sqlite redis memcache cert" github.com/gogits/gogs | |||
| go install -v -tags "sqlite redis memcache cert" | |||
| fi | |||
| @@ -8,7 +8,7 @@ github.com/Unknwon/cae = commit:2e70a1351b | |||
| github.com/Unknwon/com = commit:2cbcbc6916 | |||
| github.com/Unknwon/goconfig = commit:0f8d8dc1c0 | |||
| github.com/Unknwon/i18n = commit:47baeff8d0 | |||
| github.com/Unknwon/macaron = | |||
| github.com/Unknwon/macaron = commit:4927b78ad9 | |||
| github.com/codegangsta/cli = commit:7381bc4e62 | |||
| github.com/go-sql-driver/mysql = commit:8111ee3ec3 | |||
| github.com/go-xorm/core = commit:750aae0fa5 | |||
| @@ -17,13 +17,14 @@ github.com/gogits/gfm = commit:40f747a9c0 | |||
| github.com/gogits/oauth2 = commit:99cbec870a | |||
| github.com/lib/pq = commit:b021d0ef20 | |||
| github.com/macaron-contrib/cache = commit:204d8e5137 | |||
| github.com/macaron-contrib/captcha = | |||
| github.com/macaron-contrib/csrf = | |||
| github.com/macaron-contrib/i18n = | |||
| github.com/macaron-contrib/session = | |||
| github.com/macaron-contrib/captcha = commit:d37d37eeea | |||
| github.com/macaron-contrib/csrf = commit:8e980822b0 | |||
| github.com/macaron-contrib/i18n = commit:2246f45894 | |||
| github.com/macaron-contrib/session = commit:42ad41e323 | |||
| github.com/macaron-contrib/toolbox = commit:57127bcc89 | |||
| github.com/mattn/go-sqlite3 = commit:a80c27ba33 | |||
| github.com/nfnt/resize = commit:581d15cb53 | |||
| github.com/russross/blackfriday = commit:05b8cefd6a | |||
| github.com/saintfish/chardet = commit:3af4cd4741 | |||
| [res] | |||
| @@ -1,11 +1,11 @@ | |||
| Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://drone.io/github.com/gogits/gogs/latest) | |||
| Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://travis-ci.org/gogits/gogs) | |||
| ===================== | |||
| Gogs(Go Git Service) is a painless self-hosted Git Service written in Go. | |||
|  | |||
| ##### Current version: 0.5.4 Beta | |||
| ##### Current version: 0.5.5 Beta | |||
| ### NOTICES | |||
| @@ -32,11 +32,13 @@ The goal of this project is to make the easiest, fastest and most painless way t | |||
| - Activity timeline | |||
| - SSH/HTTP(S) protocol support | |||
| - SMTP/LDAP/reverse proxy authentication support | |||
| - Reverse proxy suburl support | |||
| - Register/delete/rename account | |||
| - Create/manage/delete organization with team management | |||
| - Create/migrate/mirror/delete/watch/rename/transfer public/private repository | |||
| - Repository viewer/release/issue tracker | |||
| - Repository and Organization level webhooks | |||
| - Repository Git hooks | |||
| - Add/remove repository collaborators | |||
| - Gravatar and cache support | |||
| - Mail service(register, issue) | |||
| @@ -44,7 +46,7 @@ The goal of this project is to make the easiest, fastest and most painless way t | |||
| - Slack webhook integration | |||
| - Supports MySQL, PostgreSQL and SQLite3 | |||
| - Social account login(GitHub, Google, QQ, Weibo) | |||
| - Multi-language support(English, Chinese, Germany, French etc.) | |||
| - Multi-language support(English, Simplified Chinese, Traditional Chinese, Germany, French, Dutch etc.) | |||
| ## System Requirements | |||
| @@ -57,7 +59,7 @@ Make sure you install [Prerequirements](http://gogs.io/docs/installation/) first | |||
| There are 5 ways to install Gogs: | |||
| - [Install from binary](http://gogs.io/docs/installation/install_from_binary.md): **STRONGLY RECOMMENDED** | |||
| - [Install from binary](http://gogs.io/docs/installation/install_from_binary.md) | |||
| - [Install from source](http://gogs.io/docs/installation/install_from_source.md) | |||
| - [Install from packages](http://gogs.io/docs/installation/install_from_packages.md) | |||
| - [Ship with Docker](https://github.com/gogits/gogs/tree/master/docker) | |||
| @@ -1,11 +1,11 @@ | |||
| Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://drone.io/github.com/gogits/gogs/latest) | |||
| Gogs - Go Git Service [](https://app.wercker.com/project/bykey/ad0bdb0bc450ac6f09bc56b9640a50aa) [](https://travis-ci.org/gogits/gogs) | |||
| ===================== | |||
| Gogs(Go Git Service) 是一个基于 Go 语言的自助 Git 服务。 | |||
|  | |||
| ##### 当前版本:0.5.4 Beta | |||
| ##### 当前版本:0.5.5 Beta | |||
| ## 开发目的 | |||
| @@ -23,19 +23,21 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自 | |||
| - 活动时间线 | |||
| - 支持 SSH/HTTP(S) 协议 | |||
| - 支持 SMTP/LDAP/反向代理 用户认证 | |||
| - 注册/删除/重命名 用户 | |||
| - 创建/管理/删除 组织以及团队管理功能 | |||
| - 创建/迁移/镜像/删除/关注/重命名/转移 公开/私有 仓库 | |||
| - 仓库 浏览/发布/工单管理 | |||
| - 仓库和组织级别 Web 钩子 | |||
| - 添加/删除 仓库协作者 | |||
| - Gravatar 以及缓存支持 | |||
| - 邮件服务(注册、Issue) | |||
| - 支持反向代理子路径 | |||
| - 支持 注册/删除/重命名 用户 | |||
| - 支持 创建/管理/删除 组织以及团队管理功能 | |||
| - 支持 创建/迁移/镜像/删除/关注/重命名/转移 公开/私有 仓库 | |||
| - 支持仓库 浏览/发布/工单管理 | |||
| - 支持仓库和组织级别 Web 钩子 | |||
| - 支持仓库 Git 钩子 | |||
| - 支持 添加/删除 仓库协作者 | |||
| - 支持 Gravatar 以及本地缓存 | |||
| - 支持邮件服务(注册、Issue) | |||
| - 管理员面板 | |||
| - Slack Web 钩子集成 | |||
| - 支持 MySQL、PostgreSQL 以及 SQLite3 数据库 | |||
| - 社交帐号登录(GitHub、Google、QQ、微博) | |||
| - 多语言支持(英文、简体中文、德语、法语等等) | |||
| - 多语言支持(英文、简体中文、繁体中文、德语、法语、荷兰语等等) | |||
| ## 系统要求 | |||
| @@ -48,7 +50,7 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自 | |||
| 然后,您可以通过以下 5 种方式来安装 Gogs: | |||
| - [二进制安装](http://gogs.io/docs/installation/install_from_binary.md): **强烈推荐** | |||
| - [二进制安装](http://gogs.io/docs/installation/install_from_binary.md) | |||
| - [源码安装](http://gogs.io/docs/installation/install_from_source.md) | |||
| - [包管理安装](http://gogs.io/docs/installation/install_from_packages.md) | |||
| - [采用 Docker 部署](https://github.com/gogits/gogs/tree/master/docker) | |||
| @@ -1,3 +1,5 @@ | |||
| // +build cert | |||
| // Copyright 2009 The Go Authors. All rights reserved. | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| @@ -0,0 +1,34 @@ | |||
| // +build !cert | |||
| // Copyright 2009 The Go Authors. All rights reserved. | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package cmd | |||
| import ( | |||
| "fmt" | |||
| "time" | |||
| "github.com/codegangsta/cli" | |||
| ) | |||
| var CmdCert = cli.Command{ | |||
| Name: "cert", | |||
| Usage: "Generate self-signed certificate", | |||
| Description: `Generate a self-signed X.509 certificate for a TLS server. | |||
| Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`, | |||
| Action: runCert, | |||
| Flags: []cli.Flag{ | |||
| cli.StringFlag{"host", "", "Comma-separated hostnames and IPs to generate a certificate for", ""}, | |||
| cli.StringFlag{"ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521", ""}, | |||
| cli.IntFlag{"rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set", ""}, | |||
| cli.StringFlag{"start-date", "", "Creation date formatted as Jan 1 15:04:05 2011", ""}, | |||
| cli.DurationFlag{"duration", 365 * 24 * time.Hour, "Duration that certificate is valid for", ""}, | |||
| cli.BoolFlag{"ca", "whether this cert should be its own Certificate Authority", ""}, | |||
| }, | |||
| } | |||
| func runCert(ctx *cli.Context) { | |||
| fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.") | |||
| } | |||
| @@ -60,6 +60,7 @@ func runDump(ctx *cli.Context) { | |||
| z.AddFile("gogs-db.sql", path.Join(workDir, "gogs-db.sql")) | |||
| z.AddFile("custom/conf/app.ini", path.Join(workDir, "custom/conf/app.ini")) | |||
| z.AddDir("log", path.Join(workDir, "log")) | |||
| // FIXME: SSH key file. | |||
| if err = z.Close(); err != nil { | |||
| os.Remove(fileName) | |||
| log.Fatalf("Fail to save %s: %v", fileName, err) | |||
| @@ -61,10 +61,18 @@ func checkVersion() { | |||
| log.Fatal(4, "Binary and template file version does not match, did you forget to recompile?") | |||
| } | |||
| // Macaron. | |||
| // Check dependency version. | |||
| macaronVer := git.MustParseVersion(strings.Join(strings.Split(macaron.Version(), ".")[:3], ".")) | |||
| if macaronVer.LessThan(git.MustParseVersion("0.1.8")) { | |||
| log.Fatal(4, "Macaron version does not match, did you forget to update?(github.com/Unknwon/macaron)") | |||
| if macaronVer.LessThan(git.MustParseVersion("0.2.0")) { | |||
| log.Fatal(4, "Package macaron version is too old, did you forget to update?(github.com/Unknwon/macaron)") | |||
| } | |||
| i18nVer := git.MustParseVersion(i18n.Version()) | |||
| if i18nVer.LessThan(git.MustParseVersion("0.0.2")) { | |||
| log.Fatal(4, "Package i18n version is too old, did you forget to update?(github.com/macaron-contrib/i18n)") | |||
| } | |||
| sessionVer := git.MustParseVersion(session.Version()) | |||
| if sessionVer.LessThan(git.MustParseVersion("0.0.1")) { | |||
| log.Fatal(4, "Package session version is too old, did you forget to update?(github.com/macaron-contrib/session)") | |||
| } | |||
| } | |||
| @@ -88,10 +96,12 @@ func newMacaron() *macaron.Macaron { | |||
| IndentJSON: macaron.Env != macaron.PROD, | |||
| })) | |||
| m.Use(i18n.I18n(i18n.Options{ | |||
| SubURL: setting.AppSubUrl, | |||
| Langs: setting.Langs, | |||
| Names: setting.Names, | |||
| Redirect: true, | |||
| SubURL: setting.AppSubUrl, | |||
| Directory: path.Join(setting.ConfRootPath, "locale"), | |||
| CustomDirectory: path.Join(setting.CustomPath, "conf/locale"), | |||
| Langs: setting.Langs, | |||
| Names: setting.Names, | |||
| Redirect: true, | |||
| })) | |||
| m.Use(cache.Cacher(cache.Options{ | |||
| Adapter: setting.CacheAdapter, | |||
| @@ -239,6 +249,11 @@ func runWeb(*cli.Context) { | |||
| r.Post("/:authid", bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost) | |||
| r.Post("/:authid/delete", admin.DeleteAuthSource) | |||
| }) | |||
| m.Group("/notices", func(r *macaron.Router) { | |||
| r.Get("", admin.Notices) | |||
| r.Get("/:id:int/delete", admin.DeleteNotice) | |||
| }) | |||
| }, adminReq) | |||
| m.Get("/:username", ignSignIn, user.Profile) | |||
| @@ -313,6 +328,12 @@ func runWeb(*cli.Context) { | |||
| r.Get("/hooks/:id", repo.WebHooksEdit) | |||
| r.Post("/hooks/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost) | |||
| r.Post("/hooks/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost) | |||
| m.Group("/hooks/git", func(r *macaron.Router) { | |||
| r.Get("", repo.GitHooks) | |||
| r.Get("/:name", repo.GitHooksEdit) | |||
| r.Post("/:name", repo.GitHooksEditPost) | |||
| }, middleware.GitHookService()) | |||
| }) | |||
| }, reqSignIn, middleware.RepoAssignment(true), reqTrueOwner) | |||
| @@ -70,6 +70,8 @@ ENABLE_CACHE_AVATAR = false | |||
| ENABLE_NOTIFY_MAIL = false | |||
| ; More detail: https://github.com/gogits/gogs/issues/165 | |||
| ENABLE_REVERSE_PROXY_AUTHENTICATION = false | |||
| ; Repository Git hooks | |||
| ENABLE_GIT_HOOKS = false | |||
| [webhook] | |||
| ; Cron task interval in minutes | |||
| @@ -256,5 +258,5 @@ CONN = | |||
| MAX_GITDIFF_LINES = 10000 | |||
| [i18n] | |||
| LANGS = en-US,zh-CN,de-DE,fr-CA | |||
| NAMES = English,简体中文,Deutsch,Français | |||
| LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL | |||
| NAMES = English,简体中文,繁體中文,Deutsch,Français,Nederlands | |||
| @@ -5,9 +5,9 @@ dashboard = Dashboard | |||
| explore = Erkunden | |||
| help = Hilfe | |||
| sign_in = Anmelden | |||
| social_sign_in = Social Sign In: 2nd Step <small>associate account</small> | |||
| social_sign_in = Anmeldung über soziales Konto: zweiter Schritt <small>Konto verknüpfen</small> | |||
| sign_out = Abmelden | |||
| sign_up = Sign up | |||
| sign_up = Registrieren | |||
| register = Registrieren | |||
| website = Webseite | |||
| version = Version | |||
| @@ -18,7 +18,7 @@ language = Sprache | |||
| username = Benutzername | |||
| email = E-Mail | |||
| password = Passwort | |||
| re_type = wiederholen | |||
| re_type = Passwort bestätigen | |||
| captcha = Captcha | |||
| repository = Repository | |||
| @@ -60,11 +60,11 @@ domain = Domain | |||
| domain_helper = Dies hat Auswirkung auf die SSH clone URLs. | |||
| app_url = Anwendungs-URL | |||
| app_url_helper = Dies hat Auswirkung auf die HTTP/HTTPS clone URLs und für die E-Mails. | |||
| email_title = E-Mail-Service-Einstellungen(Optional) | |||
| email_title = E-Mail-Service-Einstellungen (optional) | |||
| smtp_host = SMTP Host | |||
| mailer_user = Sender E-mail | |||
| mailer_password = Sender Passwort | |||
| notify_title = Benachrichtigungseinstellungen(Optional) | |||
| notify_title = Benachrichtigungseinstellungen (optional) | |||
| register_confirm = Registrierungsbestätigung aktvieren | |||
| mail_notify = E-Mail-Benachrichtgung aktivieren | |||
| admin_title = Konto-Einstellungen für den Administrator | |||
| @@ -85,14 +85,14 @@ install_success = Herzlich Willkommen! Wir sind froh, dass du dich für Gogs ent | |||
| [home] | |||
| uname_holder = Benutzername oder E-Mail | |||
| password_holder = Passwort | |||
| switch_dashboard_context = Switch Dashboard Context | |||
| switch_dashboard_context = Dashboard Kontext wechseln | |||
| my_repos = Meine Repositorys | |||
| collaborative_repos = Gemeinschaftliche Repositorys | |||
| my_orgs = Meine Organisationen | |||
| my_mirrors = Meine Spiegel | |||
| [explore] | |||
| repos = Repositories | |||
| repos = Repositorys | |||
| [auth] | |||
| create_new_account = Neues Konto erstellen | |||
| @@ -104,9 +104,9 @@ remember_me = angemeldet bleiben | |||
| forgot_password= Passwort vergessen | |||
| forget_password = Passwort vergessen? | |||
| sign_up_now = Du willst ein Konto? Jetzt registrieren! | |||
| confirmation_mail_sent_prompt = Eine neu Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden um die Registrierung abzuschließen. | |||
| sign_in_email = Melden dich mit deiner E-Mail-Adresse an | |||
| active_your_account = Aktivieren dein Konto | |||
| confirmation_mail_sent_prompt = Eine neue Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Kontrolliere dein Postfach innerhalb der nächsten %d Stunden, um die Registrierung abzuschließen. | |||
| sign_in_email = Melde dich mit deiner E-Mail-Adresse an | |||
| active_your_account = Aktiviere dein Konto | |||
| resent_limit_prompt = Es tut uns leid, du sendest zu häufig Aktivierungs-E-Mails. Bitte warte 3 Minuten. | |||
| has_unconfirmed_mail = Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Falls du noch keine Bestätigungs-E-Mail erhalten hast oder eine neue senden musst, klicke auf den unteren Button. | |||
| resend_mail = Hier klicken, um deine Aktivierungs-E-Mail erneut zu versenden | |||
| @@ -122,7 +122,7 @@ UserName = Benutzername | |||
| RepoName = Repository-Name | |||
| Email = E-Mail-Adresse | |||
| Password = Passwort | |||
| Retype = Passwort erneut eingeben | |||
| Retype = Passwort bestätigen | |||
| SSHTitle = SSH-Schlüsselname | |||
| HttpsUrl = HTTPS-URL | |||
| PayloadUrl = Payload-URL | |||
| @@ -158,7 +158,7 @@ enterred_invalid_password = Bitte stelle sicher, dass das eingegebene Passwort r | |||
| user_not_exist = Angegebener Benutzer existiert nicht. | |||
| last_org_owner = Der zu entfernende Benutzer ist der letzte Teambesitzer. Es muss einen anderen Besitzer geben. | |||
| invalid_ssh_key = Leider sind wir nicht in der Lage, Ihren SSH-Schlüssel zu überprüfen: %s | |||
| invalid_ssh_key = Leider sind wir nicht in der Lage, deinen SSH-Schlüssel zu überprüfen: %s | |||
| auth_failed = Authentifizierung fehlgeschlagen: %v | |||
| still_own_repo = Dein Konto besitzt noch Repositorys. Diese müssen zuerst gelöscht oder übertragen werden. | |||
| @@ -166,6 +166,15 @@ org_still_own_repo = Diese Organisation besitzt noch Repositorys. Diese müssen | |||
| still_own_user = Diese Authentifizierung wird noch von einigen Benutzern genutzt. Entferne diese zuvor und lösche erneut. | |||
| [user] | |||
| change_avatar = Ändere dein Profilbild auf gravatar.com | |||
| join_on = Registriert | |||
| repositories = Repositorys | |||
| activity = Öffentliche Aktivität | |||
| followers = Folgen | |||
| starred = Markiert | |||
| following = Folgt | |||
| [settings] | |||
| profile = Profil | |||
| password = Passwort | |||
| @@ -260,7 +269,7 @@ settings.transfer = Besitz übertragen | |||
| settings.transfer_desc = Übertrage dieses Repository einem anderen Benutzer oder einer Organisation. | |||
| settings.new_owner_has_same_repo = Neuer Eigentümer hat bereits ein Repository mit dem gleichen Namen. | |||
| settings.delete = Repository löschen | |||
| settings.delete_desc = Wenn dieses Repository gelöschet ist, gibt es keinen Weg zurück. Sei dir sicher! | |||
| settings.delete_desc = Wenn dieses Repository gelöscht ist, gibt es keinen Weg zurück. Sei dir sicher! | |||
| settings.update_settings_success = Repository-Optionen aktualisiert | |||
| settings.transfer_owner = Neuer Besitzer | |||
| settings.make_transfer = übertragen | |||
| @@ -285,7 +294,7 @@ settings.update_webhook = Webhook aktualisieren | |||
| settings.update_hook_success = Webhook aktualisiert | |||
| settings.delete_webhook = Webhook löschen | |||
| settings.recent_deliveries = letzte Zustellungen | |||
| settings.hook_type = Hook Type | |||
| settings.hook_type = Hook Typ | |||
| settings.add_slack_hook_desc = Add <a href="http://slack.com">Slack</a> integration to your repository. | |||
| settings.slack_token = Token | |||
| settings.slack_domain = Domain | |||
| @@ -321,7 +330,7 @@ settings.delete = Organisation löschen | |||
| settings.delete_account = Diese Organisation löschen | |||
| settings.delete_prompt = Die Organisation wird dauerhaft gelöscht. Dies kann <strong>NICHT</strong> rückgängig gemacht werden! | |||
| settings.confirm_delete_account = Löschen | |||
| settings.hooks_desc = Add webhooks that will be triggered for <strong>all repositories</strong> under this organization. | |||
| settings.hooks_desc = Füge Webhooks hinzu, die für <strong>alle</strong> Repositorys dieser Organisation ausgelöst werden. | |||
| members.public = Öffentlich | |||
| members.public_helper = Privat machen | |||
| @@ -372,8 +381,8 @@ next = vor | |||
| dashboard.statistic = Statistik | |||
| dashboard.operations = Operationen | |||
| dashboard.system_status = System-Monitor-Status | |||
| dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organizationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositorys, <b>%d</b> watches, <b>%d</b> stars, <b>%d</b> actions, <b>%d</b> Zugriffe, <b>%d</b> issues, <b>%d</b> Kommentare, <b>%d</b> soziale Konten, <b>%d</b> follows, <b>%d</b> Spiegel, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Milestones, <b>%d</b> Labels, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge. | |||
| dashboard.operation_name = Operation Name | |||
| dashboard.statistic_info = GoGS Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organisationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositorys, <b>%d</b> Beobachtungen, <b>%d</b> Markierungen, <b>%d</b> Aktionen, <b>%d</b> Zugriffe, <b>%d</b> Issues, <b>%d</b> Kommentare, <b>%d</b> soziale Konten, <b>%d</b> Folgende, <b>%d</b> Spiegel, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Milestones, <b>%d</b> Labels, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge. | |||
| dashboard.operation_name = Name der Operation | |||
| dashboard.operation_switch = Switch | |||
| dashboard.operation_run = Ausführen | |||
| dashboard.clean_unbind_oauth = ungebundene OAuths bereinigen | |||
| @@ -436,8 +445,8 @@ repos.repo_manage_panel = Repositorys | |||
| repos.owner = Besitzer | |||
| repos.name = Name | |||
| repos.private = Privat | |||
| repos.watches = Watches | |||
| repos.stars = Stars | |||
| repos.watches = Beobachtungen | |||
| repos.stars = Markierungen | |||
| repos.issues = Issues | |||
| auths.auth_manage_panel = Authentifizierung | |||
| @@ -493,11 +502,11 @@ config.db_path_helper = (nur für "sqlite3") | |||
| config.service_config = Service-Einstellungen | |||
| config.register_email_confirm = E-Mail-Bestätigung bei Registrierung | |||
| config.disable_register = Registrierung deaktivieren | |||
| config.require_sign_in_view = Require Sign In View | |||
| config.require_sign_in_view = Ansehen erfordert Registrierung | |||
| config.mail_notify = E-Mail-Benachrichtigung | |||
| config.enable_cache_avatar = Avatar-Cache aktivieren | |||
| config.active_code_lives = Active Code Lives | |||
| config.reset_password_code_lives = Reset Password Code Lives | |||
| config.active_code_lives = Aktivierungscode Lebensdauer | |||
| config.reset_password_code_lives = Passwortcode Lebensdauer | |||
| config.webhook_config = Webhook-Einstellungen | |||
| config.task_interval = Task-Intervall | |||
| config.deliver_timeout = Zeitlimit für Zustellung | |||
| @@ -516,7 +525,7 @@ config.session_config = Session-Einstellungen | |||
| config.session_provider = Session-Provider | |||
| config.provider_config = Provider-Einstellungen | |||
| config.cookie_name = Cookie-Name | |||
| config.enable_set_cookie = Enable Set Cookie | |||
| config.enable_set_cookie = Cookies einschalten | |||
| config.gc_interval_time = GC-Intervallzeit | |||
| config.session_life_time = Session-Lebensdauer | |||
| config.https_only = nur HTTPS | |||
| @@ -534,7 +543,7 @@ monitor.name = Name | |||
| monitor.schedule = Zeitplan | |||
| monitor.next = nächste Ausführung | |||
| monitor.previous = letzte Ausführung | |||
| monitor.execute_times = Execute Times | |||
| monitor.execute_times = Anzahl Ausführungen | |||
| monitor.process = Laufende Prozesse | |||
| monitor.desc = Beschreibung | |||
| monitor.start = Startzeit | |||
| @@ -159,6 +159,7 @@ user_not_exist = Given user does not exist. | |||
| last_org_owner = The user to remove is the last member in owner team. There must be another owner. | |||
| invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s | |||
| unable_verify_ssh_key = Gogs cannot verify your SSH key, but we assume that is valid, please make sure yourself. | |||
| auth_failed = Authentication failed: %v | |||
| still_own_repo = Your account still have ownership of repository, you have to delete or transfer them first. | |||
| @@ -273,6 +274,9 @@ tags = Tags | |||
| issues = Issues | |||
| commits = Commits | |||
| releases = Releases | |||
| file_raw = Raw | |||
| file_history = History | |||
| file_view_raw = View Raw | |||
| commits.commits = Commits | |||
| commits.search = Search commits | |||
| @@ -287,6 +291,7 @@ settings = Settings | |||
| settings.options = Options | |||
| settings.collaboration = Collaboration | |||
| settings.hooks = Webhooks | |||
| settings.githooks = Git Hooks | |||
| settings.deploy_keys = Deploy Keys | |||
| settings.basic_settings = Basic Settings | |||
| settings.danger_zone = Danger Zone | |||
| @@ -308,8 +313,14 @@ settings.confirm_delete = Confirm Deletion | |||
| settings.add_collaborator = Add New Collaborator | |||
| settings.add_collaborator_success = New collaborator has been added. | |||
| settings.remove_collaborator_success = Collaborator has been removed. | |||
| settings.user_is_org_member = User is organization member who cannot be added as a collaborator. | |||
| settings.add_webhook = Add Webhook | |||
| settings.hooks_desc = Webhooks allow external services to be notified when certain events happen on Gogs. When the specified events happen, we'll send a POST request to each of the URLs you provide. Learn more in our <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>. | |||
| settings.githooks_desc = Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations. | |||
| settings.githook_edit_desc = If hook is not active, sample content will be presented. Leave content to be blank will disable this hook. | |||
| settings.githook_name = Hook Name | |||
| settings.githook_content = Hook Content | |||
| settings.update_githook = Update Hook | |||
| settings.remove_hook_success = Webhook has been removed. | |||
| settings.add_webhook_desc = We’ll send a <code>POST</code> request to the URL below with details of any subscribed events. You can also specify which data format you'd like to receive (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). More information can be found in <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks Guide</a>. | |||
| settings.payload_url = Payload URL | |||
| @@ -330,6 +341,15 @@ settings.slack_token = Token | |||
| settings.slack_domain = Domain | |||
| settings.slack_channel = Channel | |||
| diff.browse_source = Browse Source | |||
| diff.parent = parent | |||
| diff.commit = commit | |||
| diff.data_not_available = Diff Data Not Available. | |||
| diff.show_diff_stats = Show Diff Stats | |||
| diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong> | |||
| diff.bin = BIN | |||
| diff.view_file = View File | |||
| [org] | |||
| org_name_holder = Organization Name | |||
| org_name_helper = Great organization names are short and memorable. | |||
| @@ -402,6 +422,7 @@ teams.admin_permission_desc = This team grants <strong>Admin</strong> access: me | |||
| teams.repositories = Team Repositories | |||
| teams.add_team_repository = Add Team Repository | |||
| teams.remove_repo = Remove | |||
| teams.add_nonexistent_repo = The repository you're trying to add does not exist, please create it first. | |||
| [admin] | |||
| dashboard = Dashboard | |||
| @@ -410,6 +431,7 @@ organizations = Organizations | |||
| repositories = Repositories | |||
| authentication = Authentications | |||
| config = Configuration | |||
| notices = System Notices | |||
| monitor = Monitoring | |||
| prev = Prev. | |||
| next = Next | |||
| @@ -587,12 +609,21 @@ monitor.desc = Description | |||
| monitor.start = Start Time | |||
| monitor.execute_time = Execution Time | |||
| notices.system_notice_list = System Notices | |||
| notices.type = Type | |||
| notices.type_1 = Repository | |||
| notices.desc = Description | |||
| notices.op = Op. | |||
| notices.delete_success = System notice has been successfully deleted. | |||
| [action] | |||
| create_repo = created repository <a href="%s/%s">%s</a> | |||
| commit_repo = pushed to <a href="%s/%s/src/%s">%s</a> at <a href="%s/%s">%s</a> | |||
| create_issue = opened issue <a href="%s/%s/issues/%s">%s#%s</a> | |||
| comment_issue = commented on issue <a href="%s/%s/issues/%s">%s#%s</a> | |||
| transfer_repo = transfered repository <code>%s</code> to <a href="/%s%s">%s</a> | |||
| push_tag = pushed tag <a href="%s/%s/src/%s">%s</a> to <a href="%s/%s">%s</a> | |||
| compare_2_commits = View comparison for these 2 commits | |||
| [tool] | |||
| ago = ago | |||
| @@ -0,0 +1,585 @@ | |||
| app_desc = Een pijnloze self-hosted Git-dienst geschreven in Go | |||
| home = Home | |||
| dashboard = Dashboard | |||
| explore = Verkennen | |||
| help = Help | |||
| sign_in = Inloggen | |||
| social_sign_in = Social netwerk inlog: tweede stap <small>account koppelen</small> | |||
| sign_out = Afmelden | |||
| sign_up = Aanmelden | |||
| register = Registreer | |||
| website = Website | |||
| version = Versie | |||
| page = Pagina | |||
| template = Template | |||
| language = Taal | |||
| username = Gebruikersnaam | |||
| email = E-mail | |||
| password = Wachttwoord | |||
| re_type = Verificatie | |||
| captcha = Captcha | |||
| repository = Repositorie | |||
| organization = Organisatie | |||
| mirror = Mirror | |||
| new_repo = Nieuwe repositorie | |||
| new_migrate = Nieuwe migratie | |||
| new_org = Nieuwe organisatie | |||
| manage_org = Beheer organisaties | |||
| admin_panel = Adminpaneel | |||
| account_settings = Accountinstellingen | |||
| settings = Instellingen | |||
| news_feed = Nieuwsfeed | |||
| pull_requests = Pull-aanvragen | |||
| issues = Issues | |||
| cancel = Annuleer | |||
| [home] | |||
| uname_holder = Gebruikersnaam of e-mail | |||
| password_holder = Wachtwoord | |||
| switch_dashboard_context = Wissel voorpaginacontext | |||
| my_repos = Mijn repositories | |||
| collaborative_repos = Gedeelde repositories | |||
| my_orgs = Mijn organisaties | |||
| my_mirrors = Mijn mirrors | |||
| [auth] | |||
| create_new_account = Maak nieuw account aan | |||
| register_hepler_msg = Heeft u al een account? Meld u nu aan! | |||
| social_register_hepler_msg = Heeft u al een account? Koppel nu! | |||
| disable_register_prompt = Sorry, registratie is uitgeschakeld. Neem contact op met de beheerder van deze site. | |||
| disable_register_mail = Sorry, bevestiging van registratie per e-mail is uitgeschakeld. | |||
| remember_me = Onthoud mij | |||
| forgot_password = Wachtwoord vergeten | |||
| forget_password = Wachtwoord vergeten? | |||
| sign_up_now = Een account nodig? Meld u nu aan. | |||
| confirmation_mail_sent_prompt = Een bevestigingsemail is gestuurd naar <b>%s</b>, Bevestig u aanvraag binnen %d uren om uw registratie te voltooien. | |||
| sign_in_email = Meld u aan met uw e-mailadres | |||
| active_your_account = Activeer uw account | |||
| resent_limit_prompt = Sorry, u heeft te snel na elkaar een aanvraag gedaan voor een activatie mail. Wacht drie minuten voor uw volgende aanvraag. | |||
| has_unconfirmed_mail = Beste %s, u heeft een onbevestigde e-mailadres (<b>%s</b>). Als u nog geen bevestiging per e-mail heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop. | |||
| resend_mail = Klik hier om uw activatie mail nog een keer te verzenden | |||
| send_reset_mail = Klik hier om uw wachtwoord reset mail (nogmaals) te versturen | |||
| reset_password = Reset uw wachtwoord | |||
| invalid_code = Sorry, uw bevestigingscode is verlopen of niet meer geldig. | |||
| reset_password_helper = Klik hier om uw wachtwoord opnieuw in te stellen. | |||
| password_too_short = De lengte van uw wachtwoord moet minimaal zes karakters zijn. | |||
| email_not_associate = Dit e-mailadres is niet gekoppeld aan een account. | |||
| [form] | |||
| UserName = Gebruikersnaam | |||
| RepoName = Repositorie naam | |||
| Email = e-mailadres | |||
| Password = Wachtwoord | |||
| Retype = Verifieer wachtwoord | |||
| SSHTitle = SSH sleutel naam | |||
| HttpsUrl = HTTPS URL | |||
| PayloadUrl = Payload URL | |||
| TeamName = Team naam | |||
| AuthName = Autorisatienaam | |||
| require_error = kan niet leeg zijn. | |||
| alpha_dash_error = moet een valide alfanumeriek of dash(-_) karakter zijn. | |||
| alpha_dash_dot_error = moet een valide alfanumeriek, dash(-_) of (.) punt karakter zijn. | |||
| min_size_error = moet minimaal %s karakters bevatten. | |||
| max_size_error = mag maximaal %s karakters bevatten. | |||
| email_error = is niet een valide e-mail adres. | |||
| url_error = is niet een valide URL. | |||
| unknown_error = Onbekende fout: | |||
| captcha_incorrect = Captcha komt niet overeen. | |||
| password_not_match = Wachtwoord en verificatie wachtwoord komen niet overeen. | |||
| username_been_taken = Gebruikersnaam is al in gebruik. | |||
| repo_name_been_taken = Repositorie naam is al in gebruik. | |||
| org_name_been_taken = Organisatie naam is al in gebruik. | |||
| team_name_been_taken = Team naam is al in gebruik. | |||
| email_been_used = e-mailadres is al in gebruik. | |||
| ssh_key_been_used = Openbare sleutel naam is al in gebruik. | |||
| illegal_username = Gebruikersnaam bevat illegale karakters. | |||
| illegal_repo_name = Repositorie naam bevat illegale karakters. | |||
| illegal_org_name = Organisatie naam bevat illegale karakters. | |||
| illegal_team_name = Team naam bevat illegale karakters. | |||
| username_password_incorrect = Gebruikersnaam of wachtwoord is niet correct. | |||
| enterred_invalid_repo_name = U heeft een onjuiste repositorie naam ingevoerd. | |||
| enterred_invalid_owner_name = U heeft een onjuiste eigenaar ingevoerd. | |||
| enterred_invalid_password = U heeft een onjuiste wachtwoord ingevoerd. | |||
| user_not_exist = Gegeven gebruiker bestaat niet. | |||
| last_org_owner = De gebruiker die u probeert te verwijderen is het enige lid (eigenaar) van dit team. U moet eerst nieuwe lid (eigenaar) aanstellen. | |||
| invalid_ssh_key = Sorry, we zijn niet in staat om uw SSH-sleutel te verifiëren: %s | |||
| auth_failed = Verificatie mislukt: %v | |||
| still_own_repo = Uw account heeft nog een eigendom op een repositorie. U moet deze eerst verwijderen of overdragen. | |||
| org_still_own_repo = De organisatie heeft nog eigendomen op repositories. U moet deze eerst verwijderen of overdragen. | |||
| still_own_user = Deze authenticatie methode wordt nog gebruikt door sommige gebruikers. U moet hen eerst verplaatsen of verwijderen. | |||
| AdminEmail = E-mail beheerder | |||
| [settings] | |||
| profile = Profiel | |||
| password = Wachtwoord | |||
| ssh_keys = SSH-sleutels | |||
| social = Sociale netwerk-accounts | |||
| orgs = Organisaties | |||
| delete = Verwijder account | |||
| public_profile = Openbaar profiel | |||
| profile_desc = Uw e-mailadres is openbaar zichtbaar en zal gebruikt worden gebruikt voor alle account gerlateerde berichtgevingen en web bewerking gemaakt via de website. | |||
| full_name = Volledige naam | |||
| website = Website | |||
| location = Locatie | |||
| update_profile = Profile bijwerken | |||
| update_profile_success = Uw profiel is succesvol bijgewerkt. | |||
| change_password = Verander wachtwoord | |||
| old_password = Huidige wachtwoord | |||
| new_password = Nieuw wachtwoord | |||
| password_incorrect = Huidig wachtwoord is niet correct. | |||
| change_password_success = Wachtwoord is succesvol gewijzigd. U kunt nu met uw nieuwe wachtwoord inloggen. | |||
| manage_ssh_keys = Beheer SSH sleutels | |||
| add_key = Sleutel toevoegen | |||
| ssh_desc = Dit is een lijst van alle SSH sleutels die gekoppeld zijn aan uw account. Verwijder alle sleutels die u niet herkent. | |||
| ssh_helper = <strong>Hulp nodig?</strong> Bekijk onze help pagina's over <a href="https://help.github.com/articles/generating-ssh-keys">SSH sleutels genereeren</a> of over <a href="https://help.github.com/ssh-issues/">meest voorkomende SSH problemen</a>. | |||
| add_new_key = SSH sleutel toevoegen | |||
| key_name = Sleutel naam | |||
| key_content = Inhoud | |||
| add_key_success = Nieuwe SSH sleutel is toegevoegd! | |||
| delete_key = Verwijder | |||
| add_on = Toegevoegd op | |||
| last_used = Laatst gebruikt op | |||
| no_activity = Geen recente activiteiten | |||
| manage_social = Beheer gekoppelde sociale accounts | |||
| social_desc = Dit is een lijst van de bijbehorende sociale accounts koppelingen, Verwijder eventueel koppelingen die u niet herkent. | |||
| unbind = Loskoppelen | |||
| unbind_success = Sociaal account is ontkoppeld. | |||
| delete_account = Verwijder uw account | |||
| delete_prompt = Deze handeling zal uw account definitief verwijderen, u kunt dit <strong> NIET </strong> terug draaien! | |||
| confirm_delete_account = Bevestig verwijdering | |||
| uid = uid | |||
| change_username = Username veranderd | |||
| change_username_desc = Gebruikersnaam is gewijzigd. Wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op uw account. | |||
| continue = Doorgaan | |||
| cancel = Annuleren | |||
| delete_account_title = Account verwijderen | |||
| delete_account_desc = Dit account zal permanent worden verwijderd. Wilt u doorgaan? | |||
| [repo] | |||
| owner = Eigenaar | |||
| repo_name = Repositorie naam | |||
| repo_name_helper = Een goede repositorie naam is kort, memorabel en <strong>uniek</strong>. | |||
| visibility = Zichtbaarheid | |||
| visiblity_helper = Deze repositorie is <span class="label label-red label-radius">prive</span> | |||
| repo_desc = Omschrijving | |||
| repo_lang = Taal | |||
| repo_lang_helper = Selecteer een .gitignore bestand | |||
| license = Licentie | |||
| license_helper = Selecteer een licentie bestand | |||
| init_readme = Initialiseer deze repositorie met een README.md | |||
| create_repo = Nieuwe Repositorie | |||
| default_branch = Standaard branch | |||
| mirror_interval = Mirror interval(uur) | |||
| goget_meta = Go-Get Meta | |||
| goget_meta_helper = Deze repositorie is nu beschikbaar voor <span class="label label-blue label-radius">Go-Get</span> | |||
| need_auth = Autorisatie vereist | |||
| migrate_type = Migratie type | |||
| migrate_type_helper = Deze repositorie zal een <span class="label label-blue label-radius">mirror</span> worden | |||
| migrate_repo = Migreer repositorie | |||
| clone_helper = Hulp nodig bij het klonen? Kijk dan <a target="_blank" href="http://git-scm.com/book/en/Git-Basics-Getting-a-Git-Repository">hier</a> voor hulp! | |||
| unwatch = Negeren | |||
| watch = Volgen | |||
| unstar = Ontster | |||
| star = Ster | |||
| fork = Fork | |||
| settings = Instellingen | |||
| settings.options = Opties | |||
| settings.collaboration = Samenwerking | |||
| settings.hooks = Webhooks | |||
| settings.deploy_keys = Installeer sleutels | |||
| settings.basic_settings = Basis instellingen | |||
| settings.danger_zone = Gevaren zone | |||
| settings.site = Officiële site | |||
| settings.update_settings = Instellingen bewerken | |||
| settings.transfer = Eigendom overdragen | |||
| settings.transfer_desc = Draag deze repo over aan een andere gebruiker of een organisatie waar u beheerders rechten heeft. | |||
| settings.delete = Verwijder deze repositorie | |||
| settings.delete_desc = Als u eenmaal een repositorie verwijderd is er geen weg terug. Gelieve zeker te zijn van uw acties. | |||
| settings.update_settings_success = Repositorie instellingen zijn succesvol bijgewerkt. | |||
| settings.transfer_owner = Nieuwe eigenaar | |||
| settings.make_transfer = Maak overdracht | |||
| settings.confirm_delete = Bevestig verwijdering | |||
| settings.add_collaborator = Nieuwe medewerker toevoegen | |||
| settings.add_collaborator_success = medewerker is toegevoegd. | |||
| settings.remove_collaborator_success = medewerker is verwijderd. | |||
| settings.add_webhook = Webhook toevoegen | |||
| settings.hooks_desc = Webhooks maken het mogelijk om externe diensten te waaarschuwen wanneer zich bepaalde gebeurtenissen voordoen op Gogs . Wanneer de opgegeven gebeurtenissen gebeuren , zullen we een POST-aanvraag aan alle URL's die u verstrekt sturen . Lees meer in onze <a target="_blank" href="http://gogs.io/docs/features/webhook.html"> Webhooks gids </a>. | |||
| settings.remove_hook_success = Webhook is verwijderd. | |||
| settings.add_webhook_desc = We sturen een <code>POST</code> verzoek aan de onderstaande URL met de details van het geplaatste evenementen. U kunt ook aangeven welke data u wilt ontvangen (JSON, <code>x-www-form-urlencoded</code>, <em>etc</em>). U kunt meer informatie vinden in onze <a target="_blank" href="http://gogs.io/docs/features/webhook.html"> webhooks gids</a>. | |||
| settings.payload_url = Payload URL | |||
| settings.content_type = Content type | |||
| settings.secret = Geheim | |||
| settings.event_desc = Bij welke gebeurtenissen wilt u dat deze webhook getriggerd wordt? | |||
| settings.event_push_only = Alleen bij de <code>push</code> event. | |||
| settings.active = Actief | |||
| settings.active_helper = We zullen details van de gebeurtenissen af leveren wanneer deze webhook wordt geactiveerd. | |||
| settings.add_hook_success = Nieuwe webhook toegevoegd. | |||
| settings.update_webhook = Bewerk webhook | |||
| settings.update_hook_success = Webhook is bijgewerkt. | |||
| settings.delete_webhook = Webhook verwijderen | |||
| settings.recent_deliveries = Recente bezorgingen | |||
| copy_link = Kopieer | |||
| click_to_copy = Kopieer link naar plakbord | |||
| copied = Gekopieerd | |||
| no_desc = Geen omschrijving | |||
| quick_guide = Snelstart gids | |||
| clone_this_repo = Kloon deze repositorie | |||
| create_new_repo_command = Maak een nieuwe repositorie aan vanaf de console | |||
| push_exist_repo = Push een bestaande repositorie vanaf de console | |||
| branch = Aftakking | |||
| tree = Boom | |||
| branch_and_tags = Aftakkingen & labels | |||
| branches = Aftakkingen | |||
| tags = Labels | |||
| issues = Issues | |||
| commits = Commits | |||
| releases = Publicaties | |||
| commits.commits = Commits | |||
| commits.search = Zoeken | |||
| commits.find = zoek | |||
| commits.author = Auteur | |||
| commits.message = Bericht | |||
| commits.date = Datum | |||
| commits.older = Ouder | |||
| commits.newer = Nieuwer | |||
| settings.change_reponame = Repositorienaam aangepast | |||
| settings.change_reponame_desc = De repositorienaam is veranderd. Wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op deze repositorie. | |||
| settings.new_owner_has_same_repo = De nieuwe eigenaar heeft al een repositorie met deze naam | |||
| settings.transfer_notices = <p> - U kan uw toegang verliezen als de nieuwe eigenaar een individuele gebruiker is</p> <p> - . . U zal uw toegang behouden als de nieuwe eigenaar een organisatie is en u één van de eigenaren bent</p> | |||
| settings.transfer_succeed = Eigendom repositorie succesvol overgedragen | |||
| settings.hook_type = Type hook | |||
| settings.add_slack_hook_desc = Voeg een <a href="http://slack.com">Slack</a> integratie toe aan uw repositorie. | |||
| settings.slack_token = Slack token | |||
| settings.slack_domain = Slack domein | |||
| settings.slack_channel = Slack kanaal | |||
| [org] | |||
| org_name_holder = Organisatienaam | |||
| org_name_helper = Een goede organisatienaam is kort en memorabel. | |||
| org_email_helper = Alle notificaties en bevestigingen worden op het e-mailadres van de organisatie ontvangen. | |||
| create_org = Nieuwe organisatie aanmaken | |||
| repo_updated = Geupdate | |||
| people = Mensen | |||
| invite_someone = Iemand uitnodigen | |||
| teams = Teams | |||
| lower_members = leden | |||
| lower_repositories = repositories | |||
| create_new_team = Nieuw team aanmaken | |||
| org_desc = Omschrijving | |||
| team_name = Teamnaam | |||
| team_desc = Omschrijving | |||
| team_name_helper = U gebruikt deze naam om dit team te vermelden in conversaties. | |||
| team_desc_helper = Waar gaat dit team doen? | |||
| team_permission_desc = Welke privileges zou dit team moeten hebben? | |||
| settings = Instellingen | |||
| settings.options = Opties | |||
| settings.full_name = Volledige naam | |||
| settings.website = Website | |||
| settings.location = Locatie | |||
| settings.update_settings = Instellingen bijwerken | |||
| settings.update_setting_success = Organisatie instellingen zijn succesvol bijgewerkt. | |||
| settings.delete = Verwijder organisatie | |||
| settings.delete_account = Verwijder deze organisatie | |||
| settings.delete_prompt = Deze actie zal de origanisatie permanent verwijderen. U kunt dit <strong>NIET</strong> terug draaien! | |||
| settings.confirm_delete_account = Bevestig verwijdering | |||
| members.public = Openbaar | |||
| members.public_helper = maak prive | |||
| members.private = Prive | |||
| members.private_helper = maak openbaar | |||
| members.owner = Eigenaar | |||
| members.member = Lid | |||
| members.conceal = Verbergen | |||
| members.remove = Verwijderen | |||
| members.leave = Verlaat | |||
| members.invite_desc = Begin met het typen van een gebruikersnaam om een nieuw lid aan %s uit te nodigen: | |||
| members.invite_now = Nu uitnodigen | |||
| teams.join = Lid worden | |||
| teams.leave = Vertlaat | |||
| teams.read_access = Leestoegang | |||
| teams.read_access_helper = Dit team is in staat om zijn repositories te bekijken en te klonen. | |||
| teams.write_access = Schrijf toegang | |||
| teams.write_access_helper = Dit team is in staat om zijn repositories te bekijken en push aanvragen te verwerken. | |||
| teams.admin_access = Beheerder toegang | |||
| teams.admin_access_helper = Dit team is in staat om push & pull aanvragen te verwerken en om nieuwe medewerkers toe te voegen. | |||
| teams.no_desc = Dit team heeft geen omschrijving | |||
| teams.settings = Instellingen | |||
| teams.owners_permission_desc = Eigenaren hebben volledige toegang tot <strong>alle repositories</strong> en hebben <strong>beheerder rechten</strong> over de organisatie. | |||
| teams.members = Team leden | |||
| teams.update_settings = Instellingen bijwerken | |||
| teams.delete_team = Verwijder deze team | |||
| teams.add_team_member = Nieuwe team lid aanmaken | |||
| teams.delete_team_success = Gekozen team is succesvol verwijderd. | |||
| teams.read_permission_desc = Dit team heeft <strong>Lees</strong> rechten : leden kunnen repositories lezen en klonen. | |||
| teams.write_permission_desc = Dit team heeft <strong>Schrijf</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken. | |||
| teams.admin_permission_desc = Dit team heeft <strong>Beheerders</strong> rechten : leden kunnen repositories lezen en push aanvragen verwerken en medewerkers toevoegen. | |||
| teams.repositories = Teamrepositories | |||
| teams.add_team_repository = Nieuwe teamrepositorie aanmaken | |||
| teams.remove_repo = Verwijder | |||
| settings.change_orgname = Organisatie naam veranderd | |||
| settings.change_orgname_desc = De naam van de organisatie is veranderd, wilt u doorgaan? Dit zal gevolgen hebben voor alle koppelingen die betrekking hebben op deze organisatie. | |||
| settings.delete_org_title = Verwijderen organsiatie | |||
| settings.delete_org_desc = Deze organisatie zal permanent worden verwijderd, wilt u doorgaan? | |||
| settings.hooks_desc = Een webhook toevoegen die door <strong>alle repositories</strong> in deze organisatie getriggerd kan worden. | |||
| teams.delete_team_title = Team verwijderen | |||
| teams.delete_team_desc = Dit team zal worden verwijderd. De leden van dit team zullen toegang tot alle repositories van het team verliezen. Wilt u doorgaan? | |||
| [admin] | |||
| dashboard = Dashboard | |||
| users = Gebruikers | |||
| organizations = Orgranisaties | |||
| repositories = Repositories | |||
| authentication = Autenticaties | |||
| config = Configuratie | |||
| monitor = Bijhouden | |||
| prev = Vorige | |||
| next = Volgende | |||
| dashboard.statistic = Statistieken | |||
| dashboard.operations = Bewerkingen | |||
| dashboard.system_status = Status Systeemmonitor | |||
| dashboard.statistic_info = Gogs database heeft <b>%d</b> gebruikers, <b>%d</b> organisaties, <b>%d</b> openbare sleutels, <b>%d</b> repositories, <b>%d</b> volgers, <b>%d</b> sterren, <b>%d</b> acties, <b>%d</b> participanten, <b>%d</b> issues, <b>%d</b> reacties, <b>%d</b> sociale accounten, <b>%d</b> volgers, <b>%d</b> mirrors, <b>%d</b> publicaties, <b>%d</b> login bronnen, <b>%d</b> webhooks, <b>%d</b> mijlpalen, <b>%d</b> labels, <b>%d</b> hook taken, <b>%d</b> teams, <b>%d</b> bijgewerkte taken, <b>%d</b> bijlagen. | |||
| dashboard.operation_name = Bewerking naam | |||
| dashboard.operation_switch = Omschakelen | |||
| dashboard.operation_run = Uitvoeren | |||
| dashboard.clean_unbind_oauth = Clean unbound OAuths | |||
| dashboard.delete_inactivate_accounts = Verwijder alle inactieve accounts | |||
| dashboard.server_uptime = Uptime server | |||
| dashboard.current_goroutine = Huidige Goroutines | |||
| dashboard.current_memory_usage = Huidige geheugen gebruik | |||
| dashboard.total_memory_allocated = Totaal toegewezen geheugen | |||
| dashboard.memory_obtained = Geheugen gebruikt | |||
| dashboard.pointer_lookup_times = Pointer Lookup Times | |||
| dashboard.memory_allocate_times = Memory Allocate Times | |||
| dashboard.memory_free_times = Memory Free Times | |||
| dashboard.current_heap_usage = Current Heap Usage | |||
| dashboard.heap_memory_obtained = Heap Memory Obtained | |||
| dashboard.heap_memory_idle = Heap Memory Idle | |||
| dashboard.heap_memory_in_use = Heap Memory In Use | |||
| dashboard.heap_memory_released = Heap Memory Released | |||
| dashboard.heap_objects = Heap Objects | |||
| dashboard.bootstrap_stack_usage = Bootstrap Stack Usage | |||
| dashboard.stack_memory_obtained = Stack Memory Obtained | |||
| dashboard.mspan_structures_usage = MSpan Structures Usage | |||
| dashboard.mspan_structures_obtained = MSpan Structures Obtained | |||
| dashboard.mcache_structures_usage = MCache Structures Usage | |||
| dashboard.mcache_structures_obtained = MCache Structures Obtained | |||
| dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained | |||
| dashboard.gc_metadata_obtained = GC Metadada Obtained | |||
| dashboard.other_system_allocation_obtained = Other System Allocation Obtained | |||
| dashboard.next_gc_recycle = Volgende GC recycle | |||
| dashboard.last_gc_time = Sinds vorige GC verwerkingstijd | |||
| dashboard.total_gc_time = Totaal GC verwerkingstijd | |||
| dashboard.total_gc_pause = Totaal GC verwerkingstijd | |||
| dashboard.last_gc_pause = Laatste GC verwerkingstijd | |||
| dashboard.gc_times = GC verwerkingen | |||
| users.user_manage_panel = Gebruikers beheren | |||
| users.new_account = Nieuw account aanmaken | |||
| users.name = Naam | |||
| users.activated = Geactiveerd | |||
| users.admin = Admin | |||
| users.repos = Repos | |||
| users.created = Aangemaakt | |||
| users.edit = Bewerken | |||
| users.auth_source = Autorisatiebron | |||
| users.local = Lokaal | |||
| users.auth_login_name = Autorisatie inlognaam | |||
| users.update_profile_success = Profiel is succesvol bijgewerkt. | |||
| users.edit_account = Bewerk account | |||
| users.is_activated = Dit account is geactiveerd | |||
| users.is_admin = Dit account heeft beheerdersrechten | |||
| users.update_profile = Account profiel bijwerken | |||
| users.delete_account = Dit account verwijderen | |||
| users.still_own_repo = Dit account is nog steeds eigendom van een repositorie. U moet deze repositorie eerst verwijderen of overdragen. | |||
| orgs.org_manage_panel = Organisaties beheren | |||
| orgs.name = Naam | |||
| orgs.teams = Teams | |||
| orgs.members = Leden | |||
| repos.repo_manage_panel = Repositoriebeheerpaneel | |||
| repos.owner = Eigenaar | |||
| repos.name = Naam | |||
| repos.private = Prive | |||
| repos.watches = Volgers | |||
| repos.stars = Sterren | |||
| repos.issues = Issues | |||
| auths.auth_manage_panel = Autorisatiebeheerpaneel | |||
| auths.new = Nieuwe autorisatiebron | |||
| auths.name = Naam | |||
| auths.type = Type | |||
| auths.enabled = Ingeschakeld | |||
| auths.updated = Bijgewerkt | |||
| auths.auth_type = Autorisatietype | |||
| auths.auth_name = Autorisatienaam | |||
| auths.domain = Domein | |||
| auths.host = Host | |||
| auths.port = Poort | |||
| auths.base_dn = Base DN | |||
| auths.attributes = Zoek attributen | |||
| auths.filter = Zoek filter | |||
| auths.ms_ad_sa = Ms Ad SA | |||
| auths.smtp_auth = SMTP authenticatietype | |||
| auths.smtphost = SMTP host | |||
| auths.smtpport = SMTP poort | |||
| auths.enable_tls = Activeer TLS-encryptie | |||
| auths.enable_auto_register = Activeer automatische registratie | |||
| auths.tips = Tips | |||
| auths.edit = Bewerk autorisatie-instellingen | |||
| auths.activated = Deze autorisatiemethode is geactiveerd | |||
| auths.update_success = Autorisatie-instellingen zijn succesvol bijgewerkt. | |||
| auths.update = Update autorisatie-instellingen | |||
| auths.delete = Verwijder deze autorisatie | |||
| config.server_config = Serverconfiguratie | |||
| config.app_name = Applicatienaam | |||
| config.app_ver = Applicatieversie | |||
| config.app_url = Applicatie-URL | |||
| config.domain = Domein | |||
| config.offline_mode = Offline-modus | |||
| config.disable_router_log = Router-log uitschakelen | |||
| config.run_user = Uitvoerende gebruiker | |||
| config.run_mode = Uitvoer modus | |||
| config.repo_root_path = Repositorie basis pad | |||
| config.static_file_root_path = Statische bestanden basis pad | |||
| config.log_file_root_path = Log bestand basis pad | |||
| config.script_type = Script type | |||
| config.reverse_auth_user = Reverse Authentication User | |||
| config.db_config = Databaseconfiguratie | |||
| config.db_type = Type | |||
| config.db_host = Host | |||
| config.db_name = Naam | |||
| config.db_user = Gebruiker | |||
| config.db_ssl_mode = SSL modus | |||
| config.db_ssl_mode_helper = (alleen voor "postgres") | |||
| config.db_path = Path | |||
| config.db_path_helper = (alleen voor "sqlite3") | |||
| config.service_config = Serviceconfiguratie | |||
| config.register_email_confirm = Register Email Confirmation | |||
| config.disable_register = Registratie uitgeschakeld | |||
| config.require_sign_in_view = Inloggen vereist om te kunnen inzien | |||
| config.mail_notify = E-mailnotificaties | |||
| config.enable_cache_avatar = Avatar Cache inschakelen | |||
| config.active_code_lives = Active Code Lives | |||
| config.reset_password_code_lives = Reset Password Code Lives | |||
| config.webhook_config = Webhook configuratie | |||
| config.task_interval = Taakinterval | |||
| config.deliver_timeout = Bezorging verlooptijd | |||
| config.mailer_config = Mailerconfiguatie | |||
| config.mailer_enabled = Ingeschakeld | |||
| config.mailer_name = Naam | |||
| config.mailer_host = Host | |||
| config.mailer_user = Gebruiker | |||
| config.oauth_config = OAuth-configuratie | |||
| config.oauth_enabled = Ingeschakeld | |||
| config.cache_config = Cache-configuratie | |||
| config.cache_adapter = Cache-adapter | |||
| config.cache_interval = Cache-interval | |||
| config.cache_conn = Cache-connectie | |||
| config.session_config = Sessieconfiguratie | |||
| config.session_provider = Sessieprovider | |||
| config.provider_config = Provider config | |||
| config.cookie_name = Cookie naam | |||
| config.enable_set_cookie = Set Cookie inschakelen | |||
| config.gc_interval_time = GC interval time | |||
| config.session_life_time = Sessie duur | |||
| config.https_only = Alleen HTTPS | |||
| config.cookie_life_time = Cookie duur leeftijd | |||
| config.session_hash_function = Sessie ID Hash functie | |||
| config.session_hash_key = Sessie ID Hash sleutel | |||
| config.picture_config = Foto configuratie | |||
| config.picture_service = Foto service | |||
| config.disable_gravatar = Gravatar uitschakelen | |||
| config.log_config = Logconfiguratie | |||
| config.log_mode = Log-modus | |||
| monitor.cron = Cron-taken | |||
| monitor.name = Naam | |||
| monitor.schedule = Planning | |||
| monitor.next = Volgende | |||
| monitor.previous = Vorige | |||
| monitor.execute_times = Aantal keren uitgevoerd | |||
| monitor.process = Draaiende processen | |||
| monitor.desc = Omschrijving | |||
| monitor.start = Starttijd | |||
| monitor.execute_time = Uitvoertijd | |||
| auths.delete_auth_title = Verwijderings-autorisatie | |||
| auths.delete_auth_desc = Deze autorisatiemethode wordt verwijderd. Weet u zeker dat u wilt doorgaan? | |||
| [action] | |||
| create_repo = repositorie aangemaakt in <a href="%s/%s">%s</a> | |||
| commit_repo = push update naar <a href="%s/%s/src/%s">%s</a> in <a href="%s/%s">%s</a | |||
| create_issue = opende issue in <a href="%s/%s/issues/%s">%s#%s</a> | |||
| comment_issue = reactie op issue <a href="%s/%s/issues/%s">%s#%s</a> | |||
| transfer_repo = repositorie verplaatst naar <code>%s</code> naar <a href="/%s%s">%s</a> | |||
| [tool] | |||
| ago = geleden | |||
| from_now = vanaf nu | |||
| now = nu | |||
| 1s = 1 seconde %s | |||
| 1m = 1 minuut %s | |||
| 1h = 1 uur %s | |||
| 1d = 1 dag %s | |||
| 1w = 1 week %s | |||
| 1mon = 1 maand %s | |||
| 1y = 1 jaar %s | |||
| seconds = %d seconden %s | |||
| minutes = %d minuten %s | |||
| hours = %d uur %s | |||
| days = %d dagen %s | |||
| weeks = %d weken %s | |||
| months = %d maanden %s | |||
| years = %d jaren %s | |||
| raw_seconds = seconden | |||
| raw_minutes = minuten | |||
| [install] | |||
| install = Installatie | |||
| title = Installatiestappen voor de eerste keer opstarten | |||
| requite_db_desc = Om Gogs te gebruiken is MySQL, PostgreSQL of SQLite3 vereist (SQLite3 is beschikbaar in de officiële versie). | |||
| db_type = Database-type | |||
| host = Host | |||
| user = Gebruikersnaam | |||
| password = Wachtwoord | |||
| db_name = Database naam | |||
| db_helper = Gebruik InnoDB engine met utf8_general_ci karakterset voor MySQL. | |||
| ssl_mode = SSL-modus | |||
| path = Pad | |||
| sqlite_helper = Het pad naar de SQLite3 database. | |||
| general_title = Algemene instellingen van Gogs | |||
| repo_path = Repositories basis directorie | |||
| repo_path_helper = Alle remote Git repositories worden in deze directorie opgeslagen | |||
| run_user = Uitvoerende gebruikersnaam | |||
| run_user_helper = Deze gebruiker moet toegang hebben tot de git repositorie directorie en moet Gogs kunnen starten | |||
| domain = Domein | |||
| domain_helper = Dit heeft invloed op de SSH kloon URLs | |||
| app_url = Applicatie URL | |||
| app_url_helper = Dit heeft invloed op de HTTP/HTTPS kloon urls en de urls die in de email worden gebruikt | |||
| email_title = Email service instellingen (Optioneel) | |||
| smtp_host = SMTP host | |||
| mailer_user = Afzender e-mail / gebruikersnaam | |||
| mailer_password = Wachtwoord | |||
| notify_title = Notificatie-instelligen (optioneel) | |||
| register_confirm = Activeer registratie emails | |||
| mail_notify = Activeer e-mailnotificaties | |||
| admin_title = Instellingen beheerdersaccount | |||
| admin_name = Gebruikersnaam | |||
| admin_password = Wachtwoord | |||
| confirm_password = Verifieer wachtwoord | |||
| admin_email = E-mailadres | |||
| install_gogs = Installeer Gogs | |||
| test_git_failed = Git test niet gelukt: 'git' commando %v | |||
| sqlite3_not_available = SQLite3 wordt niet ondersteund in uw versie. Gelieve de officiële versie downloaden vanaf http://gogs.io/docs/installation/install_from_binary.html, niet de gobuild versie downloaden. | |||
| invalid_db_setting = Uw database instellingen zijn niet correct: %v | |||
| invalid_repo_path = Repositorie basis pad is niet correct: %v | |||
| run_user_not_match = De uitvoerende gebruiker is niet de huidig gebruiker: %s -> %s | |||
| save_config_failed = Kan de configuratie niet opslaan: %v | |||
| invalid_admin_setting = Uw admin-instellingen zijn niet geldig: %v | |||
| install_success = Welkom! Wij zijn veheugd dat u voor Gogs heeft gekozen, veel plezier en tot ziens | |||
| [explore] | |||
| repos = Repositories | |||
| [user] | |||
| change_avatar = Verander uw avatar op Gravatar.com | |||
| join_on = Aangemeld op | |||
| repositories = repositories | |||
| activity = Openbare activiteit | |||
| followers = Volgers | |||
| starred = Sterren | |||
| following = Volgt | |||
| @@ -159,6 +159,7 @@ user_not_exist = 被操作的用户不存在! | |||
| last_org_owner = 被移除用户为最后一位管理员。请添加一位新的管理员再进行移除成员操作! | |||
| invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s | |||
| unable_verify_ssh_key = Gogs 无法验证您输入的 SSH 密钥,但我们假设那是有效的密钥,请您自行确保其有效性! | |||
| auth_failed = 授权验证失败:%v | |||
| still_own_repo = 您的帐户仍然是某些仓库的拥有者,您必须先转移或删除它们才能执行删除帐户操作! | |||
| @@ -273,6 +274,9 @@ tags = 标签列表 | |||
| issues = 工单管理 | |||
| commits = 提交历史 | |||
| releases = 版本发布 | |||
| file_raw = 原始文件 | |||
| file_history = 文件历史 | |||
| file_view_raw = 查看原始文件 | |||
| commits.commits = 次代码提交 | |||
| commits.search = 搜索提交历史 | |||
| @@ -287,6 +291,7 @@ settings = 仓库设置 | |||
| settings.options = 基本设置 | |||
| settings.collaboration = 管理协作者 | |||
| settings.hooks = 管理 Web 钩子 | |||
| settings.githooks = 管理 Git 钩子 | |||
| settings.deploy_keys = 管理部署密钥 | |||
| settings.basic_settings = 基本设置 | |||
| settings.danger_zone = 危险操作区 | |||
| @@ -308,10 +313,16 @@ settings.confirm_delete = 确认删除仓库 | |||
| settings.add_collaborator = 增加新的协作者 | |||
| settings.add_collaborator_success = 成功添加新的协作者! | |||
| settings.remove_collaborator_success = 被操作的协作者已经被收回权限! | |||
| settings.user_is_org_member = 被操作的用户是组织成员,因此无法添加为协作者! | |||
| settings.add_webhook = 添加 Web 钩子 | |||
| settings.hooks_desc = Web 钩子允许您设定在 Gogs 上发生指定事件时对指定 URL 发送 POST 通知。查看 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。 | |||
| settings.remove_hook_success = Web 钩子删除成功! | |||
| settings.add_webhook_desc = 我们会通过 <code>POST</code> 请求将订阅事件信息发送至向指定 URL 地址。您可以设置不同的数据接收方式(JSON 或 <code>x-www-form-urlencoded</code>)。 请查阅 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文档</a> 获取更多信息。 | |||
| settings.githooks_desc = Git 钩子是由 Git 本身提供的功能,以下为 Gogs 所支持的钩子列表。 | |||
| settings.githook_edit_desc = 如果钩子未启动,则会显示样例文件中的内容。如果想要删除某个钩子,则提交空白文本即可。 | |||
| settings.githook_name = 钩子名称 | |||
| settings.githook_content = 钩子文本 | |||
| settings.update_githook = 更新钩子设置 | |||
| settings.payload_url = 推送地址 | |||
| settings.content_type = 数据格式 | |||
| settings.secret = 密钥文本 | |||
| @@ -330,6 +341,15 @@ settings.slack_token = 令牌 | |||
| settings.slack_domain = 域名 | |||
| settings.slack_channel = 频道 | |||
| diff.browse_source = 浏览代码 | |||
| diff.parent = 父节点 | |||
| diff.commit = 当前提交 | |||
| diff.data_not_available = 暂无可用数据 | |||
| diff.show_diff_stats = 显示文件统计 | |||
| diff.stats_desc = 共有 <strong> %d 个文件被更改</strong>,包括 <strong>%d 次插入</strong> 和 <strong>%d 次删除</strong> | |||
| diff.bin = 二进制 | |||
| diff.view_file = 查看文件 | |||
| [org] | |||
| org_name_holder = 组织名称 | |||
| org_name_helper = 伟大的组织都有一个简短而寓意深刻的名字。 | |||
| @@ -402,6 +422,7 @@ teams.admin_permission_desc = 该团队拥有一定的 <strong>管理</strong> | |||
| teams.repositories = 团队仓库 | |||
| teams.add_team_repository = 添加团队仓库 | |||
| teams.remove_repo = 移除仓库 | |||
| teams.add_nonexistent_repo = 您尝试添加到团队的仓库不存在,请先创建仓库! | |||
| [admin] | |||
| dashboard = 控制面板 | |||
| @@ -410,6 +431,7 @@ organizations = 组织管理 | |||
| repositories = 仓库管理 | |||
| authentication = 授权认证管理 | |||
| config = 应用配置管理 | |||
| notices = 系统提示管理 | |||
| monitor = 应用监控面板 | |||
| prev = 上一页 | |||
| next = 下一页 | |||
| @@ -587,12 +609,21 @@ monitor.desc = 进程描述 | |||
| monitor.start = 开始时间 | |||
| monitor.execute_time = 已执行时间 | |||
| notices.system_notice_list = 系统提示管理 | |||
| notices.type = 提示类型 | |||
| notices.type_1 = 仓库 | |||
| notices.desc = 描述 | |||
| notices.op = 操作 | |||
| notices.delete_success = 系统提示删除成功! | |||
| [action] | |||
| create_repo = 创建了仓库 <a href="%s/%s">%s</a> | |||
| commit_repo = 推送了 <a href="%s/%s/src/%s">%s</a> 分支的代码到 <a href="%s/%s">%s</a> | |||
| create_issue = 创建了工单 <a href="%s/%s/issues/%s">%s#%s</a> | |||
| comment_issue = 评论了工单 <a href="%s/%s/issues/%s">%s#%s</a> | |||
| transfer_repo = 将仓库 <code>%s</code> 转移至 <a href="/%s%s">%s</a> | |||
| push_tag = 推送了标签 <a href="%s/%s/src/%s">%s</a> 到 <a href="%s/%s">%s</a> | |||
| compare_2_commits = 查看 2 次提交的内容对比 | |||
| [tool] | |||
| ago = 之前 | |||
| @@ -0,0 +1,642 @@ | |||
| app_desc = 基於 Go 語言的自助 Git 服務 | |||
| home = 首頁 | |||
| dashboard = 控制面版 | |||
| explore = 探索 | |||
| help = 幫助 | |||
| sign_in = 登錄 | |||
| social_sign_in = 社交帳號登錄:第 2 步 <small>關聯帳號</small> | |||
| sign_out = 退出 | |||
| sign_up = 註冊 | |||
| register = 註冊 | |||
| website = 官方網站 | |||
| version = 當前版本 | |||
| page = 頁面 | |||
| template = 模版 | |||
| language = 語言選項 | |||
| username = 用戶名 | |||
| email = 郵箱 | |||
| password = 密碼 | |||
| re_type = 確認密碼 | |||
| captcha = 驗證碼 | |||
| repository = 倉庫 | |||
| organization = 組織 | |||
| mirror = 鏡像 | |||
| new_repo = 創建新的倉庫 | |||
| new_migrate = 遷移外部倉庫 | |||
| new_org = 創建新的組織 | |||
| manage_org = 管理我的組織 | |||
| admin_panel = 管理面版 | |||
| account_settings = 帳戶設置 | |||
| settings = 帳戶設置 | |||
| news_feed = 最新活動 | |||
| pull_requests = 合併請求 | |||
| issues = 問題管理 | |||
| cancel = 取消 | |||
| [install] | |||
| install = 安裝頁面 | |||
| title = 首次執行安裝程序 | |||
| requite_db_desc = Gogs 允許後端數據庫為 MySQL、PostgreSQL 或 SQLite3,但是 SQLite3 一般只有官方二進制發行版才支持。 | |||
| db_type = 數據庫類型 | |||
| host = 數據庫主機 | |||
| user = 數據庫用戶 | |||
| password = 數據庫用戶密碼 | |||
| db_name = 數據庫名稱 | |||
| db_helper = 如果您使用 MySQL,請使用 INNODB 引擎以及 utf8_general_ci 字符集。 | |||
| ssl_mode = SSL 模式 | |||
| path = 數據庫文件路徑 | |||
| sqlite_helper = SQLite3 數據庫的文件路徑。 | |||
| general_title = 應用基本設置 | |||
| repo_path = 倉庫根目錄 | |||
| repo_path_helper = 所有 Git 遠程倉庫都將被存放於該目錄。 | |||
| run_user = 執行系統用戶 | |||
| run_user_helper = 該用戶必須具有對倉庫根目錄和執行 Gogs 的操作權限。 | |||
| domain = 域名 | |||
| domain_helper = 該設置影響 SSH 克隆地址。 | |||
| app_url = 應用 URL | |||
| app_url_helper = 該設置影響 HTTP/HTTPS 克隆地址和一些郵箱中的鏈接。 | |||
| email_title = 郵件服務設置(可選) | |||
| smtp_host = SMTP 主機 | |||
| mailer_user = 發送郵箱 | |||
| mailer_password = 發送郵箱密碼 | |||
| notify_title = 通知提醒設置(可選) | |||
| register_confirm = 啟用註冊郵箱確認 | |||
| mail_notify = 啟用郵件通知提醒 | |||
| admin_title = 管理員帳號設置 | |||
| admin_name = 管理員用戶名 | |||
| admin_password = 管理員密碼 | |||
| confirm_password = 確認密碼 | |||
| admin_email = 管理員郵箱 | |||
| install_gogs = 立即安裝 | |||
| test_git_failed = 無法識別 'git' 命令:%v | |||
| sqlite3_not_available = 您所使用的發行版本不支持 SQLite3,請從 http://gogs.io/docs/installation/install_from_binary.html 下載官方二進制發行版本,而不是 gobuild 版本。 | |||
| invalid_db_setting = 數據庫設置不正確:%v | |||
| invalid_repo_path = 倉庫根目錄設置不正確:%v | |||
| run_user_not_match = 執行系統用戶非當前用戶:%s -> %s | |||
| save_config_failed = 應用配置保存失敗:%v | |||
| invalid_admin_setting = 管理員帳戶設置不正確:%v | |||
| install_success = 您好!我們很高興您選擇使用 Gogs,祝您使用愉快,代碼從此無 BUG! | |||
| [home] | |||
| uname_holder = 用戶名或郵箱 | |||
| password_holder = 密碼 | |||
| switch_dashboard_context = 切換控制面版用戶 | |||
| my_repos = 我的倉庫 | |||
| collaborative_repos = 參與協作的倉庫 | |||
| my_orgs = 我的組織 | |||
| my_mirrors = 我的鏡像 | |||
| [explore] | |||
| repos = 探索倉庫 | |||
| [auth] | |||
| create_new_account = 創建帳戶 | |||
| register_hepler_msg = 已經註冊?立即登錄! | |||
| social_register_hepler_msg = 已經註冊?立即綁定! | |||
| disable_register_prompt = 對不起,註冊功能已被關閉。請聯系網站管理員。 | |||
| disable_register_mail = 對不起,註冊郵箱確認功能已被關閉。 | |||
| remember_me = 記住登錄 | |||
| forgot_password = 忘記密碼 | |||
| forget_password = 忘記密碼? | |||
| sign_up_now = 還沒帳戶?馬上註冊。 | |||
| confirmation_mail_sent_prompt = 一封新的確認郵件已經被發送至 <b>%s</b>,請檢查您的收件箱並在 %d 小時內完成確認註冊操作。 | |||
| sign_in_email = 登錄到您的郵箱 | |||
| active_your_account = 激活您的帳戶 | |||
| resent_limit_prompt = 對不起,您請求發送激活郵件過於頻繁,請等待 3 分鐘後再試! | |||
| has_unconfirmed_mail = %s 您好,系統檢測到您有一封發送至 <b>%s</b> 但未被確認的郵件。如果您未收到激活郵件,或需要重新發送,請單擊下方的按鈕。 | |||
| resend_mail = 單擊此處重新發送確認郵件 | |||
| email_not_associate = 您輸入的郵箱地址未被關聯到任何帳號! | |||
| send_reset_mail = 單擊此處(重新)發送您的密碼重置郵件 | |||
| reset_password = 重置密碼 | |||
| invalid_code = 對不起,您的確認代碼已過期或已失效。 | |||
| reset_password_helper = 單擊此處重置密碼 | |||
| password_too_short = 密碼長度不能少於 6 位! | |||
| [form] | |||
| UserName = 用戶名 | |||
| RepoName = 倉庫名稱 | |||
| Email = 郵箱地址 | |||
| Password = 密碼 | |||
| Retype = 確認密碼 | |||
| SSHTitle = SSH 密鑰名稱 | |||
| HttpsUrl = HTTPS URL 地址 | |||
| PayloadUrl = 推送地址 | |||
| TeamName = 團隊名稱 | |||
| AuthName = 認證名稱 | |||
| AdminEmail = 管理員郵箱 | |||
| require_error = 不能為空。 | |||
| alpha_dash_error = 必須為英文字母、阿拉伯數字或橫線(-_)。 | |||
| alpha_dash_dot_error = 必須為英文字母、阿拉伯數字、橫線(-_)或點。 | |||
| min_size_error = 長度最小為 %s 個字符。 | |||
| max_size_error = 長度最大為 %s 個字符。 | |||
| email_error = 不是一個有效的郵箱地址。 | |||
| url_error = 不是一個有效的 URL。 | |||
| unknown_error = 未知錯誤: | |||
| captcha_incorrect = 驗證碼未匹配。 | |||
| password_not_match = 密碼與確認密碼未匹配。 | |||
| username_been_taken = 用戶名已經被佔用。 | |||
| repo_name_been_taken = 倉庫名稱已經被佔用。 | |||
| org_name_been_taken = 組織名稱已經被佔用。 | |||
| team_name_been_taken = 團隊名稱已經被佔用。 | |||
| email_been_used = 郵箱地址已經被使用。 | |||
| ssh_key_been_used = SSH 密鑰已經被使用。 | |||
| illegal_username = 您的用戶名包含不合法字符。 | |||
| illegal_repo_name = 倉庫名稱包含不合法字符。 | |||
| illegal_org_name = 組織名稱包含不合法字符。 | |||
| illegal_team_name = 團隊名稱包含不合法字符。 | |||
| username_password_incorrect = 用戶名或密碼不正確。 | |||
| enterred_invalid_repo_name = 請檢查您輸入的倉庫名稱是正確。 | |||
| enterred_invalid_owner_name = 請檢查您輸入的新所有者用戶名是否正確。 | |||
| enterred_invalid_password = 請檢查您輸入的密碼是否正確。 | |||
| user_not_exist = 被操作的用戶不存在! | |||
| last_org_owner = 被移除用戶為最後一位管理員。請添加一位新的管理員再進行移除成員操作! | |||
| invalid_ssh_key = 很抱歉,我們無法驗證您輸入的 SSH 密鑰:%s | |||
| auth_failed = 授權驗證失敗:%v | |||
| still_own_repo = 您的帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作! | |||
| org_still_own_repo = 該組織仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除組織操作! | |||
| still_own_user = 該授權認證依舊被部分用戶使用,請先刪除該部分用戶後再試! | |||
| [user] | |||
| change_avatar = 到 gravatar.com 上修改您的頭像 | |||
| join_on = 加入於 | |||
| repositories = 倉庫列表 | |||
| activity = 公開活動 | |||
| followers = 關註者 | |||
| starred = 已點讚 | |||
| following = 關註中 | |||
| [settings] | |||
| profile = 個人信息 | |||
| password = 修改密碼 | |||
| ssh_keys = 管理 SSH 密鑰 | |||
| social = 社交帳號綁定 | |||
| orgs = 管理組織 | |||
| delete = 刪除帳戶 | |||
| uid = 用戶 ID | |||
| public_profile = 公開信息 | |||
| profile_desc = 您的郵箱地址將會被公開,並被用於接收帳戶的所有提醒和通知。 | |||
| full_name = 自定義名稱 | |||
| website = 個人網站 | |||
| location = 所在地區 | |||
| update_profile = 更新信息 | |||
| update_profile_success = 您的個人信息更新成功! | |||
| change_username = 用戶名將被修改 | |||
| change_username_desc = 用戶名被修改,您確定要繼續操作嗎?這將會影響到所有與您帳戶有關的鏈接。 | |||
| continue = 繼續操作 | |||
| cancel = 取消操作 | |||
| change_password = 修改密碼 | |||
| old_password = 當前密碼 | |||
| new_password = 新的密碼 | |||
| password_incorrect = 當前密碼不正確! | |||
| change_password_success = 密碼修改成功!您現在可以使用新的密碼登錄。 | |||
| manage_ssh_keys = 管理 SSH 密鑰 | |||
| add_key = 增加密鑰 | |||
| ssh_desc = 以下是與您帳戶所關聯的 SSH 密鑰,如果您發現有陌生的密鑰,請立即刪除它! | |||
| ssh_helper = <strong>需要幫助?</strong> 請查看有關 <a href="https://help.github.com/articles/generating-ssh-keys">如何生成 SSH 密鑰</a> 或 <a href="https://help.github.com/ssh-issues/">常見 SSH 問題</a> 尋找答案。 | |||
| add_new_key = 增加 SSH 密鑰 | |||
| key_name = 密鑰名稱 | |||
| key_content = 密鑰內容 | |||
| add_key_success = 新的 SSH 密鑰添加成功! | |||
| delete_key = 刪除 | |||
| add_on = 增加於 | |||
| last_used = 上次使用在 | |||
| no_activity = 沒有最近活動 | |||
| manage_social = 管理關聯社交帳戶 | |||
| social_desc = 以下是與您帳戶所關聯的社交帳號,如果您發現有陌生的關聯,請立即解除綁定! | |||
| unbind = 解除綁定 | |||
| unbind_success = 社交帳號解除綁定成功! | |||
| delete_account = 刪除當前帳戶 | |||
| delete_prompt = 刪除操作會永久清除您的帳戶信息,並且 <strong>不可恢復</strong>! | |||
| confirm_delete_account = 確認刪除帳戶 | |||
| delete_account_title = 帳戶刪除操作 | |||
| delete_account_desc = 該帳戶將被永久性刪除,您確定要繼續操作嗎? | |||
| [repo] | |||
| owner = 擁有者 | |||
| repo_name = 倉庫名稱 | |||
| repo_name_helper = 偉大的倉庫名稱一般都較短、令人深刻並且 <strong>獨一無二</strong> 的。 | |||
| visibility = 可見度 | |||
| visiblity_helper = 本倉庫將是 <span class="label label-red label-radius">私有的</span> | |||
| repo_desc = 倉庫描述 | |||
| repo_lang = 倉庫語言 | |||
| repo_lang_helper = 請選擇 .gitignore 文件 | |||
| license = 授權許可 | |||
| license_helper = 請選擇授權許可文件 | |||
| init_readme = 使用 README.md 文件初始化倉庫 | |||
| create_repo = 創建倉庫 | |||
| default_branch = 默認分支 | |||
| mirror_interval = 鏡像同步周期(小時) | |||
| goget_meta = Go-Get 支持 | |||
| goget_meta_helper = 本倉庫將可以通過 <span class="label label-blue label-radius">Go Get</span> 獲取 | |||
| need_auth = 需要授權驗證 | |||
| migrate_type = 遷移類型 | |||
| migrate_type_helper = 本倉庫將是 <span class="label label-blue label-radius">鏡像</span> | |||
| migrate_repo = 遷移倉庫 | |||
| copy_link = 復製鏈接 | |||
| click_to_copy = 復製到剪切簿 | |||
| copied = 復製成功 | |||
| clone_helper = 不知道如何操作?訪問 <a target="_blank" href="http://git-scm.com/book/zh/Git-基礎-取得項目的-Git-倉庫">此處</a> 查看幫助! | |||
| unwatch = 取消關註 | |||
| watch = 關註 | |||
| unstar = 取消點讚 | |||
| star = 點讚 | |||
| fork = 派生 | |||
| no_desc = 暫無描述 | |||
| quick_guide = 快速幫助 | |||
| clone_this_repo = 克隆當前倉庫 | |||
| create_new_repo_command = 從命令行創建一個新的倉庫 | |||
| push_exist_repo = 從命令行推送已經創建的倉庫 | |||
| branch = 分支 | |||
| tree = 目錄樹 | |||
| branch_and_tags = 分支與標籤 | |||
| branches = 分支列表 | |||
| tags = 標籤列表 | |||
| issues = 問題管理 | |||
| commits = 提交歷史 | |||
| releases = 版本發佈 | |||
| commits.commits = 次代碼提交 | |||
| commits.search = 搜索提交歷史 | |||
| commits.find = 查找 | |||
| commits.author = 作者 | |||
| commits.message = 備註 | |||
| commits.date = 提交日期 | |||
| commits.older = 更舊的提交 | |||
| commits.newer = 更新的提交 | |||
| settings = 倉庫設置 | |||
| settings.options = 基本設置 | |||
| settings.collaboration = 管理協作者 | |||
| settings.hooks = 管理 Web 鉤子 | |||
| settings.githooks = 管理 Git 鉤子 | |||
| settings.deploy_keys = 管理部署密鑰 | |||
| settings.basic_settings = 基本設置 | |||
| settings.danger_zone = 危險操作區 | |||
| settings.site = 官方網站 | |||
| settings.update_settings = 更新倉庫設置 | |||
| settings.change_reponame = 倉庫名稱將被修改 | |||
| settings.change_reponame_desc = 倉庫名稱被修改,您確定要繼續操作嗎?這將會影響到所有與該倉庫有關的鏈接。 | |||
| settings.transfer = 轉移倉庫所有權 | |||
| settings.transfer_desc = 您可以將倉庫轉移至您擁有管理員權限的帳戶或組織。 | |||
| settings.new_owner_has_same_repo = 新的倉庫擁有者已經存在同名倉庫! | |||
| settings.delete = 刪除本倉庫 | |||
| settings.delete_desc = 刪除倉庫操作不可逆轉,請三思而後行。 | |||
| settings.transfer_notices = <p>- 如果您轉移給個人用戶,您將對倉庫失去所有權限。</p><p>- 如果您轉移給您作為擁有者的組織,則可繼續保持操作權限。</p> | |||
| settings.update_settings_success = 倉庫設置更新成功! | |||
| settings.transfer_owner = 新擁有者 | |||
| settings.make_transfer = 確認轉移倉庫 | |||
| settings.transfer_succeed = 倉庫所有權轉移成功! | |||
| settings.confirm_delete = 確認刪除倉庫 | |||
| settings.add_collaborator = 增加新的協作者 | |||
| settings.add_collaborator_success = 成功添加新的協作者! | |||
| settings.remove_collaborator_success = 被操作的協作者已經被收回權限! | |||
| settings.add_webhook = 添加 Web 鉤子 | |||
| settings.hooks_desc = Web 鉤子允許您設定在 Gogs 上發生指定事件時對指定 URL 發送 POST 通知。查看 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文檔</a> 獲取更多信息。 | |||
| settings.remove_hook_success = Web 鉤子刪除成功! | |||
| settings.add_webhook_desc = 我們會通過 <code>POST</code> 請求將訂閱事件信息發送至向指定 URL 地址。您可以設置不同的數據接收方式(JSON 或 <code>x-www-form-urlencoded</code>)。 請查閱 <a target="_blank" href="http://gogs.io/docs/features/webhook.html">Webhooks 文檔</a> 獲取更多信息。 | |||
| settings.githooks_desc = Git 鉤子是由 Git 本身提供的功能,以下為 Gogs 所支持的鉤子列表。 | |||
| settings.githook_edit_desc = 如果鉤子未啟動,則會顯示樣例文件中的內容。如果想要刪除某個鉤子,則提交空白文本即可。 | |||
| settings.githook_name = 鉤子名稱 | |||
| settings.githook_content = 鉤子文本 | |||
| settings.update_githook = 更新鉤子設置 | |||
| settings.payload_url = 推送地址 | |||
| settings.content_type = 數據格式 | |||
| settings.secret = 密鑰文本 | |||
| settings.event_desc = 請設置您希望觸發 Web 鉤子的事件: | |||
| settings.event_push_only = 只推送 <code>push</code> 事件。 | |||
| settings.active = 是否激活 | |||
| settings.active_helper = 當指定事件發生時我們將會觸發此 Web 鉤子。 | |||
| settings.add_hook_success = Web 鉤子添加成功! | |||
| settings.update_webhook = 更新 Web 鉤子 | |||
| settings.update_hook_success = Web 鉤子更新成功! | |||
| settings.delete_webhook = 刪除 Web 鉤子 | |||
| settings.recent_deliveries = 最近推送記錄 | |||
| settings.hook_type = 鉤子類型 | |||
| settings.add_slack_hook_desc = 為您的倉庫增加 <a href="http://slack.com">Slack</a> 集成 | |||
| settings.slack_token = 令牌 | |||
| settings.slack_domain = 域名 | |||
| settings.slack_channel = 頻道 | |||
| [org] | |||
| org_name_holder = 組織名稱 | |||
| org_name_helper = 偉大的組織都有一個簡短而寓意深刻的名字。 | |||
| org_email_helper = 組織的郵箱用於接收所有通知和確認郵件。 | |||
| create_org = 創建組織 | |||
| repo_updated = 最後更新於 | |||
| people = 組織成員 | |||
| invite_someone = 邀請他人加入 | |||
| teams = 組織團隊 | |||
| lower_members = 名成員 | |||
| lower_repositories = 個倉庫 | |||
| create_new_team = 創建新的團隊 | |||
| org_desc = 組織描述 | |||
| team_name = 團隊名稱 | |||
| team_desc = 團隊描述 | |||
| team_name_helper = 您可以使用該名稱來通知改組全體成員。 | |||
| team_desc_helper = 一句話描述這個團隊是做什麼的。 | |||
| team_permission_desc = 請選擇該團隊所具有的權限等級: | |||
| settings = 組織設置 | |||
| settings.options = 基本設置 | |||
| settings.full_name = 組織全名 | |||
| settings.website = 官方網站 | |||
| settings.location = 所在地區 | |||
| settings.update_settings = 更新組織設置 | |||
| settings.change_orgname = 組織名稱將被修改 | |||
| settings.change_orgname_desc = 組織名稱被修改,您確定要繼續操作嗎?這將會影響到所有與該組織有關的鏈接。 | |||
| settings.update_setting_success = 組織設置更新成功! | |||
| settings.delete = 刪除組織 | |||
| settings.delete_account = 刪除當前組織 | |||
| settings.delete_prompt = 刪除操作會永久清除該組織的信息,並且 <strong>不可恢復</strong>! | |||
| settings.confirm_delete_account = 確認刪除組織 | |||
| settings.delete_org_title = 組織刪除操作 | |||
| settings.delete_org_desc = 該組織將被永久性刪除,您確定要繼續操作嗎? | |||
| settings.hooks_desc = 在此處添加的 Web 鉤子將會應用到該組織下的 <strong>所有倉庫</strong>。 | |||
| members.public = 公開成員 | |||
| members.public_helper = 設為私有 | |||
| members.private = 私有成員 | |||
| members.private_helper = 設為公開 | |||
| members.owner = 管理員 | |||
| members.member = 普通成員 | |||
| members.conceal = 隱藏身份 | |||
| members.remove = 移除成員 | |||
| members.leave = 離開組織 | |||
| members.invite_desc = 請輸入被邀請到組織 %s 的用戶名稱: | |||
| members.invite_now = 立即邀請 | |||
| teams.join = 加入團隊 | |||
| teams.leave = 離開團隊 | |||
| teams.read_access = 讀取權限 | |||
| teams.read_access_helper = 這個團隊將擁有查看和克隆所屬倉庫的權限。 | |||
| teams.write_access = 寫入權限 | |||
| teams.write_access_helper = 這個團隊將擁有查看、克隆和推送所屬倉庫的權限。 | |||
| teams.admin_access = 管理權限 | |||
| teams.admin_access_helper = 這個團隊將擁有查看、克隆、推送和添加其他組織成員到團隊的權限。 | |||
| teams.no_desc = 該團隊暫無描述 | |||
| teams.settings = 團隊設置 | |||
| teams.owners_permission_desc = 管理員團隊對 <strong>所有倉庫</strong> 具有操作權限,且對組織具有 <strong>管理員權限</strong>。 | |||
| teams.members = 團隊成員 | |||
| teams.update_settings = 更新團隊設置 | |||
| teams.delete_team = 刪除當前團隊 | |||
| teams.add_team_member = 添加團隊成員 | |||
| teams.delete_team_title = 團隊刪除操作 | |||
| teams.delete_team_desc = 刪除操作會永久清除有關該團隊的信息,您確定要繼續操作嗎?團隊成員可能會失去對某些倉庫的操作權限。 | |||
| teams.delete_team_success = 指定團隊刪除成功! | |||
| teams.read_permission_desc = 該團隊擁有對所屬倉庫的 <strong>讀取</strong> 權限,團隊成員可以進行查看和克隆等只讀操作。 | |||
| teams.write_permission_desc = 該團隊擁有對所屬倉庫的 <strong>讀取</strong> 和 <strong>寫入</strong> 的權限。 | |||
| teams.admin_permission_desc = 該團隊擁有一定的 <strong>管理</strong> 權限,團隊成員可以讀取、克隆、推送以及添加其它倉庫協作者。 | |||
| teams.repositories = 團隊倉庫 | |||
| teams.add_team_repository = 添加團隊倉庫 | |||
| teams.remove_repo = 移除倉庫 | |||
| [admin] | |||
| dashboard = 控制面版 | |||
| users = 用戶管理 | |||
| organizations = 組織管理 | |||
| repositories = 倉庫管理 | |||
| authentication = 授權認證管理 | |||
| config = 應用配置管理 | |||
| notices = 系統提示管理 | |||
| monitor = 應用監控面版 | |||
| prev = 上一頁 | |||
| next = 下一頁 | |||
| dashboard.statistic = 應用統計數據 | |||
| dashboard.operations = 管理員操作 | |||
| dashboard.system_status = 系統監視狀態 | |||
| dashboard.statistic_info = Gogs 數據庫統計:<b>%d</b> 位用戶,<b>%d</b> 個組織,<b>%d</b> 個公鑰,<b>%d</b> 個倉庫,<b>%d</b> 個倉庫關註,<b>%d</b> 個贊,<b>%d</b> 次行為,<b>%d</b> 條權限記錄,<b>%d</b> 個問題,<b>%d</b> 次評論,<b>%d</b> 個社交帳號,<b>%d</b> 個用戶關註,<b>%d</b> 個鏡像,<b>%d</b> 個版本發佈,<b>%d</b> 個登錄源,<b>%d</b> 個 Web 鉤子,<b>%d</b> 個里程碑,<b>%d</b> 個標籤,<b>%d</b> 個鉤子任務,<b>%d</b> 個團隊,<b>%d</b> 個更新任務,<b>%d</b> 個附件。 | |||
| dashboard.operation_name = 操作名稱 | |||
| dashboard.operation_switch = 開關 | |||
| dashboard.operation_run = 執行 | |||
| dashboard.clean_unbind_oauth = 清理未綁定社交帳號 | |||
| dashboard.delete_inactivate_accounts = 刪除所有未激活帳戶 | |||
| dashboard.server_uptime = 服務執行時間 | |||
| dashboard.current_goroutine = 當前 Goroutines 數量 | |||
| dashboard.current_memory_usage = 當前內存使用量 | |||
| dashboard.total_memory_allocated = 所有被分配的內存 | |||
| dashboard.memory_obtained = 內存佔用量 | |||
| dashboard.pointer_lookup_times = 指針查找次數 | |||
| dashboard.memory_allocate_times = 內存分配次數 | |||
| dashboard.memory_free_times = 內存釋放次數 | |||
| dashboard.current_heap_usage = 當前 Heap 內存使用量 | |||
| dashboard.heap_memory_obtained = Heap 內存佔用量 | |||
| dashboard.heap_memory_idle = Heap 內存空閒量 | |||
| dashboard.heap_memory_in_use = 正在使用的 Heap 內存 | |||
| dashboard.heap_memory_released = 被釋放的 Heap 內存 | |||
| dashboard.heap_objects = Heap 對象數量 | |||
| dashboard.bootstrap_stack_usage = 啟動 Stack 使用量 | |||
| dashboard.stack_memory_obtained = 被分配的 Stack 內存 | |||
| dashboard.mspan_structures_usage = MSpan 結構內存使用量 | |||
| dashboard.mspan_structures_obtained = 被分配的 MSpan 結構內存 | |||
| dashboard.mcache_structures_usage = MCache 結構內存使用量 | |||
| dashboard.mcache_structures_obtained = 被分配的 MCache 結構內存 | |||
| dashboard.profiling_bucket_hash_table_obtained = 被分配的剖析哈希表內存 | |||
| dashboard.gc_metadata_obtained = 被分配的垃圾收集元數據內存 | |||
| dashboard.other_system_allocation_obtained = 其它被分配的系統內存 | |||
| dashboard.next_gc_recycle = 下次垃圾收集內存回收量 | |||
| dashboard.last_gc_time = 距離上次垃圾收集時間 | |||
| dashboard.total_gc_time = 垃圾收集執行時間總量 | |||
| dashboard.total_gc_pause = 垃圾收集暫停時間總量 | |||
| dashboard.last_gc_pause = 上次垃圾收集暫停時間 | |||
| dashboard.gc_times = 垃圾收集執行次數 | |||
| users.user_manage_panel = 用戶管理面版 | |||
| users.new_account = 創建新的帳戶 | |||
| users.name = 用戶名 | |||
| users.activated = 已激活 | |||
| users.admin = 管理員 | |||
| users.repos = 倉庫數 | |||
| users.created = 創建時間 | |||
| users.edit = 編輯 | |||
| users.auth_source = 認證源 | |||
| users.local = 本地 | |||
| users.auth_login_name = 認證登錄名 | |||
| users.update_profile_success = 該用戶信息更新成功! | |||
| users.edit_account = 編輯用戶信息 | |||
| users.is_activated = 該用戶已被激活 | |||
| users.is_admin = 該用戶具有管理員權限 | |||
| users.update_profile = 更新用戶信息 | |||
| users.delete_account = 刪除該用戶 | |||
| users.still_own_repo = 該帳戶仍然是某些倉庫的擁有者,您必須先轉移或刪除它們才能執行刪除帳戶操作! | |||
| orgs.org_manage_panel = 組織管理面版 | |||
| orgs.name = 組織名稱 | |||
| orgs.teams = 團隊數 | |||
| orgs.members = 成員數 | |||
| repos.repo_manage_panel = 倉庫管理界面 | |||
| repos.owner = 所有者 | |||
| repos.name = 倉庫名稱 | |||
| repos.private = 私有庫 | |||
| repos.watches = 關註數 | |||
| repos.stars = 點讚數 | |||
| repos.issues = 問題數 | |||
| auths.auth_manage_panel = 授權認證管理面版 | |||
| auths.new = 添加新的認證源 | |||
| auths.name = 認證名稱 | |||
| auths.type = 認證類型 | |||
| auths.enabled = 已啟用 | |||
| auths.updated = 最後更新時間 | |||
| auths.auth_type = 授權類型 | |||
| auths.auth_name = 授權名稱 | |||
| auths.domain = 域名 | |||
| auths.host = 主機地址 | |||
| auths.port = 主機端口 | |||
| auths.base_dn = Base DN | |||
| auths.attributes = 搜尋屬性 | |||
| auths.filter = 搜尋過濾 | |||
| auths.ms_ad_sa = Ms Ad SA | |||
| auths.smtp_auth = SMTP 授權類型 | |||
| auths.smtphost = SMTP 主機地址 | |||
| auths.smtpport = SMTP 主機端口 | |||
| auths.enable_tls = 啟用 TLS 加密 | |||
| auths.enable_auto_register = 允許授權用戶自動註冊 | |||
| auths.tips = 幫助提示 | |||
| auths.edit = 修改授權認證設置 | |||
| auths.activated = 該授權認證已經啟用 | |||
| auths.update_success = 授權認證設置更新成功! | |||
| auths.update = 更新授權認證信息 | |||
| auths.delete = 刪除該授權認證 | |||
| auths.delete_auth_title = 授權認證刪除操作 | |||
| auths.delete_auth_desc = 該授權認證將被刪除,您確定要繼續嗎? | |||
| config.server_config = 服務器配置 | |||
| config.app_name = 應用名稱 | |||
| config.app_ver = 應用版本 | |||
| config.app_url = 應用 URL | |||
| config.domain = 應用域名 | |||
| config.offline_mode = 離線模式 | |||
| config.disable_router_log = 關閉路由日志 | |||
| config.run_user = 執行用戶 | |||
| config.run_mode = 執行模式 | |||
| config.repo_root_path = 倉庫根目錄 | |||
| config.static_file_root_path = 靜態文件根目錄 | |||
| config.log_file_root_path = 日志文件根目錄 | |||
| config.script_type = 腳本類型 | |||
| config.reverse_auth_user = 反向代理認證 | |||
| config.db_config = 數據庫配置 | |||
| config.db_type = 數據庫類型 | |||
| config.db_host = 主機地址 | |||
| config.db_name = 數據庫名稱 | |||
| config.db_user = 連接用戶 | |||
| config.db_ssl_mode = SSL 模式 | |||
| config.db_ssl_mode_helper = (僅限 "postgres" 使用) | |||
| config.db_path = 數據庫路徑 | |||
| config.db_path_helper = (僅限 "sqlite3" 使用) | |||
| config.service_config = 服務配置 | |||
| config.register_email_confirm = 註冊郵件確認 | |||
| config.disable_register = 關閉註冊功能 | |||
| config.require_sign_in_view = 強制登錄瀏覽 | |||
| config.mail_notify = 郵件通知提醒 | |||
| config.enable_cache_avatar = 開啟緩存頭像 | |||
| config.active_code_lives = 激活用戶鏈接有效期 | |||
| config.reset_password_code_lives = 重置密碼鏈接有效期 | |||
| config.webhook_config = Web 鉤子配置 | |||
| config.task_interval = 任務周期 | |||
| config.deliver_timeout = 推送超時 | |||
| config.mailer_config = 郵件配置 | |||
| config.mailer_enabled = 啟用服務 | |||
| config.mailer_name = 發送者名稱 | |||
| config.mailer_host = 郵件主機地址 | |||
| config.mailer_user = 發送者帳號 | |||
| config.oauth_config = 社交帳號配置 | |||
| config.oauth_enabled = 啟用服務 | |||
| config.cache_config = Cache 配置 | |||
| config.cache_adapter = Cache 適配器 | |||
| config.cache_interval = Cache 周期 | |||
| config.cache_conn = Cache 連接字符串 | |||
| config.session_config = Session 配置 | |||
| config.session_provider = Session 提供者 | |||
| config.provider_config = 提供者配置 | |||
| config.cookie_name = Cookie 名稱 | |||
| config.enable_set_cookie = 啟用設置 Cookie | |||
| config.gc_interval_time = 垃圾收集周期 | |||
| config.session_life_time = Session 生命周期 | |||
| config.https_only = 僅限 HTTPS | |||
| config.cookie_life_time = Cookie 生命周期 | |||
| config.session_hash_function = Session ID 哈希函數 | |||
| config.session_hash_key = Session ID 哈希健值 | |||
| config.picture_config = 圖片配置 | |||
| config.picture_service = 圖片服務 | |||
| config.disable_gravatar = 禁用 Gravatar 頭像 | |||
| config.log_config = 日誌配置 | |||
| config.log_mode = 日誌模式 | |||
| monitor.cron = Cron 任務 | |||
| monitor.name = 任務名稱 | |||
| monitor.schedule = 任務安排 | |||
| monitor.next = 下次執行時間 | |||
| monitor.previous = 上次執行時間 | |||
| monitor.execute_times = 執行次數 | |||
| monitor.process = 執行中進程 | |||
| monitor.desc = 進程描述 | |||
| monitor.start = 開始時間 | |||
| monitor.execute_time = 已執行時間 | |||
| notices.system_notice_list = 系統提示管理 | |||
| notices.type = 提示類型 | |||
| notices.type_1 = 倉庫 | |||
| notices.desc = 描述 | |||
| notices.op = 操作 | |||
| notices.delete_success = 系統提示刪除成功! | |||
| [action] | |||
| create_repo = 創建了倉庫 <a href="%s/%s">%s</a> | |||
| commit_repo = 推送了 <a href="%s/%s/src/%s">%s</a> 分支的代碼到 <a href="%s/%s">%s</a> | |||
| create_issue = 創建了問題 <a href="%s/%s/issues/%s">%s#%s</a> | |||
| comment_issue = 評論了問題 <a href="%s/%s/issues/%s">%s#%s</a> | |||
| transfer_repo = 將倉庫 <code>%s</code> 轉移至 <a href="/%s%s">%s</a> | |||
| [tool] | |||
| ago = 之前 | |||
| from_now = 之後 | |||
| now = 現在 | |||
| 1s = 1 秒%s | |||
| 1m = 1 分鐘%s | |||
| 1h = 1 小時%s | |||
| 1d = 1 天%s | |||
| 1w = 1 周%s | |||
| 1mon = 1 月%s | |||
| 1y = 1 年%s | |||
| seconds = %d 秒%s | |||
| minutes = %d 分鐘%s | |||
| hours = %d 小時%s | |||
| days = %d 天%s | |||
| weeks = %d 周%s | |||
| months = %d 月%s | |||
| years = %d 年%s | |||
| raw_seconds = 秒 | |||
| raw_minutes = 分鐘 | |||
| @@ -1,12 +1,12 @@ | |||
| [unix_http_server] | |||
| file=/tmp/supervisor.sock ; path to your socket file | |||
| file=log/supervisor.sock ; path to your socket file | |||
| [supervisord] | |||
| logfile=log/supervisord.log ; supervisord log file | |||
| logfile_maxbytes=50MB ; maximum size of logfile before rotation | |||
| logfile_backups=10 ; number of backed up logfiles | |||
| loglevel=warn ; info, debug, warn, trace | |||
| pidfile=/tmp/supervisord.pid ; pidfile location | |||
| pidfile=log/supervisord.pid ; pidfile location | |||
| nodaemon=false ; run supervisord as a daemon | |||
| minfds=1024 ; number of startup file descriptors | |||
| minprocs=200 ; number of process descriptors | |||
| @@ -17,10 +17,10 @@ childlogdir=log | |||
| supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface | |||
| [supervisorctl] | |||
| serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket | |||
| serverurl=unix://log/supervisor.sock ; use a unix:// URL for a unix socket | |||
| [program:gogs] | |||
| command = /root/Developer/gopath/src/github.com/gogits/gogs/start.sh ; here must be the real url, not ~ or $GOROOT like | |||
| command = gogs_start | |||
| autostart = true | |||
| stdout_logfile = log/supervisor-gogs-stderr.log | |||
| stderr_logfile = log/supervisor-gogs-error.log | |||
| stdout_logfile = log/supervisor-gogs-out.log | |||
| stderr_logfile = log/supervisor-gogs-err.log | |||
| @@ -17,7 +17,7 @@ import ( | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| const APP_VER = "0.5.4.1003 Beta" | |||
| const APP_VER = "0.5.5.1013 Beta" | |||
| func init() { | |||
| runtime.GOMAXPROCS(runtime.NumCPU()) | |||
| @@ -181,13 +181,19 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, | |||
| commit = &base.PushCommits{} | |||
| } | |||
| refName := git.RefEndName(refFullName) | |||
| repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName) | |||
| // if not the first commit, set the compareUrl | |||
| if !strings.HasPrefix(oldCommitId, "0000000") { | |||
| commit.CompareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId) | |||
| } | |||
| bs, err := json.Marshal(commit) | |||
| if err != nil { | |||
| return errors.New("action.CommitRepoAction(json): " + err.Error()) | |||
| } | |||
| refName := git.RefEndName(refFullName) | |||
| // Change repository bare status and update last updated time. | |||
| repo, err := GetRepositoryByName(repoUserId, repoName) | |||
| if err != nil { | |||
| @@ -211,7 +217,6 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, | |||
| return errors.New("action.CommitRepoAction(NotifyWatchers): " + err.Error()) | |||
| } | |||
| //qlog.Info("action.CommitRepoAction(end): %d/%s", repoUserId, repoName) | |||
| // New push event hook. | |||
| if err := repo.GetOwner(); err != nil { | |||
| @@ -237,13 +242,6 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, | |||
| return nil | |||
| } | |||
| repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName) | |||
| compareUrl := "" | |||
| // if not the first commit, set the compareUrl | |||
| if !strings.HasPrefix(oldCommitId, "0000000") { | |||
| compareUrl = fmt.Sprintf("%s/compare/%s...%s", repoLink, oldCommitId, newCommitId) | |||
| } | |||
| pusher_email, pusher_name := "", "" | |||
| pusher, err := GetUserByName(userName) | |||
| if err == nil { | |||
| @@ -293,7 +291,7 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, | |||
| }, | |||
| Before: oldCommitId, | |||
| After: newCommitId, | |||
| CompareUrl: compareUrl, | |||
| CompareUrl: commit.CompareUrl, | |||
| } | |||
| for _, w := range ws { | |||
| @@ -0,0 +1,64 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package models | |||
| import ( | |||
| "time" | |||
| "github.com/Unknwon/com" | |||
| ) | |||
| type NoticeType int | |||
| const ( | |||
| NOTICE_REPOSITORY NoticeType = iota + 1 | |||
| ) | |||
| // Notice represents a system notice for admin. | |||
| type Notice struct { | |||
| Id int64 | |||
| Type NoticeType | |||
| Description string `xorm:"TEXT"` | |||
| Created time.Time `xorm:"CREATED"` | |||
| } | |||
| // TrStr returns a translation format string. | |||
| func (n *Notice) TrStr() string { | |||
| return "admin.notices.type_" + com.ToStr(n.Type) | |||
| } | |||
| // CreateNotice creates new system notice. | |||
| func CreateNotice(tp NoticeType, desc string) error { | |||
| n := &Notice{ | |||
| Type: tp, | |||
| Description: desc, | |||
| } | |||
| _, err := x.Insert(n) | |||
| return err | |||
| } | |||
| // CreateRepositoryNotice creates new system notice with type NOTICE_REPOSITORY. | |||
| func CreateRepositoryNotice(desc string) error { | |||
| return CreateNotice(NOTICE_REPOSITORY, desc) | |||
| } | |||
| // CountNotices returns number of notices. | |||
| func CountNotices() int64 { | |||
| count, _ := x.Count(new(Notice)) | |||
| return count | |||
| } | |||
| // GetNotices returns given number of notices with offset. | |||
| func GetNotices(num, offset int) ([]*Notice, error) { | |||
| notices := make([]*Notice, 0, num) | |||
| err := x.Limit(num, offset).Desc("id").Find(¬ices) | |||
| return notices, err | |||
| } | |||
| // DeleteNotice deletes a system notice by given ID. | |||
| func DeleteNotice(id int64) error { | |||
| _, err := x.Id(id).Delete(new(Notice)) | |||
| return err | |||
| } | |||
| @@ -31,12 +31,12 @@ var ( | |||
| ) | |||
| func init() { | |||
| tables = append(tables, new(User), new(PublicKey), | |||
| tables = append(tables, new(User), new(PublicKey), new(Follow), new(Oauth2), | |||
| new(Repository), new(Watch), new(Star), new(Action), new(Access), | |||
| new(Issue), new(Comment), new(Oauth2), new(Follow), | |||
| new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser), | |||
| new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser), | |||
| new(UpdateTask), new(Attachment)) | |||
| new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone), | |||
| new(Mirror), new(Release), new(LoginSource), new(Webhook), | |||
| new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser), | |||
| new(Notice)) | |||
| } | |||
| func LoadModelsConfig() { | |||
| @@ -845,20 +845,9 @@ func IsTeamMember(orgId, teamId, uid int64) bool { | |||
| // GetTeamMembers returns all members in given team of organization. | |||
| func GetTeamMembers(orgId, teamId int64) ([]*User, error) { | |||
| tus := make([]*TeamUser, 0, 10) | |||
| err := x.Where("org_id=?", orgId).And("team_id=?", teamId).Find(&tus) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| us := make([]*User, len(tus)) | |||
| for i, tu := range tus { | |||
| us[i], err = GetUserById(tu.Uid) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| } | |||
| return us, nil | |||
| us := make([]*User, 0, 10) | |||
| err := x.Sql("SELECT * FROM `user` JOIN `team_user` ON `team_user`.`team_id` = ? AND `team_user`.`uid` = `user`.`id`", teamId).Find(&us) | |||
| return us, err | |||
| } | |||
| // GetUserTeams returns all teams that user belongs to in given origanization. | |||
| @@ -33,6 +33,7 @@ const ( | |||
| var ( | |||
| ErrKeyAlreadyExist = errors.New("Public key already exist") | |||
| ErrKeyNotExist = errors.New("Public key does not exist") | |||
| ErrKeyUnableVerify = errors.New("Unable to verify public key") | |||
| ) | |||
| var sshOpLocker = sync.Mutex{} | |||
| @@ -108,7 +109,7 @@ var ( | |||
| // CheckPublicKeyString checks if the given public key string is recognized by SSH. | |||
| func CheckPublicKeyString(content string) (bool, error) { | |||
| if strings.ContainsAny(content, "\n\r") { | |||
| return false, errors.New("Only a single line with a single key please") | |||
| return false, errors.New("only a single line with a single key please") | |||
| } | |||
| // write the key to a file… | |||
| @@ -126,7 +127,7 @@ func CheckPublicKeyString(content string) (bool, error) { | |||
| if err != nil { | |||
| return false, errors.New("ssh-keygen -l -f: " + stderr) | |||
| } else if len(stdout) < 2 { | |||
| return false, errors.New("ssh-keygen returned not enough output to evaluate the key") | |||
| return false, errors.New("ssh-keygen returned not enough output to evaluate the key: " + stdout) | |||
| } | |||
| // The ssh-keygen in Windows does not print key type, so no need go further. | |||
| @@ -134,21 +135,22 @@ func CheckPublicKeyString(content string) (bool, error) { | |||
| return true, nil | |||
| } | |||
| fmt.Println(stdout) | |||
| sshKeygenOutput := strings.Split(stdout, " ") | |||
| if len(sshKeygenOutput) < 4 { | |||
| return false, errors.New("Not enough fields returned by ssh-keygen -l -f") | |||
| return false, ErrKeyUnableVerify | |||
| } | |||
| // Check if key type and key size match. | |||
| keySize, err := com.StrTo(sshKeygenOutput[0]).Int() | |||
| if err != nil { | |||
| return false, errors.New("Cannot get key size of the given key") | |||
| keySize := com.StrTo(sshKeygenOutput[0]).MustInt() | |||
| if keySize == 0 { | |||
| return false, errors.New("cannot get key size of the given key") | |||
| } | |||
| keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1]) | |||
| if minimumKeySize := MinimumKeySize[keyType]; minimumKeySize == 0 { | |||
| return false, errors.New("Sorry, unrecognized public key type") | |||
| return false, errors.New("sorry, unrecognized public key type") | |||
| } else if keySize < minimumKeySize { | |||
| return false, fmt.Errorf("The minimum accepted size of a public key %s is %d", keyType, minimumKeySize) | |||
| return false, fmt.Errorf("the minimum accepted size of a public key %s is %d", keyType, minimumKeySize) | |||
| } | |||
| return true, nil | |||
| @@ -204,7 +206,7 @@ func AddPublicKey(key *PublicKey) (err error) { | |||
| if err != nil { | |||
| return errors.New("ssh-keygen -l -f: " + stderr) | |||
| } else if len(stdout) < 2 { | |||
| return errors.New("Not enough output for calculating fingerprint") | |||
| return errors.New("not enough output for calculating fingerprint: " + stdout) | |||
| } | |||
| key.Fingerprint = strings.Split(stdout, " ")[1] | |||
| @@ -23,6 +23,7 @@ import ( | |||
| "github.com/Unknwon/cae/zip" | |||
| "github.com/Unknwon/com" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/git" | |||
| "github.com/gogits/gogs/modules/log" | |||
| "github.com/gogits/gogs/modules/process" | |||
| @@ -48,7 +49,7 @@ var ( | |||
| ) | |||
| var ( | |||
| DescriptionPattern = regexp.MustCompile(`https?://\S+`) | |||
| DescPattern = regexp.MustCompile(`https?://\S+`) | |||
| ) | |||
| func LoadRepoConfig() { | |||
| @@ -165,7 +166,9 @@ type Repository struct { | |||
| } | |||
| func (repo *Repository) GetOwner() (err error) { | |||
| repo.Owner, err = GetUserById(repo.OwnerId) | |||
| if repo.Owner == nil { | |||
| repo.Owner, err = GetUserById(repo.OwnerId) | |||
| } | |||
| return err | |||
| } | |||
| @@ -182,6 +185,14 @@ func (repo *Repository) IsOwnedBy(u *User) bool { | |||
| return repo.OwnerId == u.Id | |||
| } | |||
| func (repo *Repository) HasAccess(uname string) bool { | |||
| if err := repo.GetOwner(); err != nil { | |||
| return false | |||
| } | |||
| has, _ := HasAccess(uname, path.Join(repo.Owner.Name, repo.Name), READABLE) | |||
| return has | |||
| } | |||
| // DescriptionHtml does special handles to description and return HTML string. | |||
| func (repo *Repository) DescriptionHtml() template.HTML { | |||
| sanitize := func(s string) string { | |||
| @@ -189,7 +200,7 @@ func (repo *Repository) DescriptionHtml() template.HTML { | |||
| ss := html.EscapeString(s) | |||
| return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, ss, ss) | |||
| } | |||
| return template.HTML(DescriptionPattern.ReplaceAllStringFunc(repo.Description, sanitize)) | |||
| return template.HTML(DescPattern.ReplaceAllStringFunc(base.XSSString(repo.Description), sanitize)) | |||
| } | |||
| // IsRepositoryExist returns true if the repository with given name under user has already existed. | |||
| @@ -660,7 +671,7 @@ func RepoPath(userName, repoName string) string { | |||
| func TransferOwnership(u *User, newOwner string, repo *Repository) error { | |||
| newUser, err := GetUserByName(newOwner) | |||
| if err != nil { | |||
| return err | |||
| return fmt.Errorf("fail to get new owner(%s): %v", newOwner, err) | |||
| } | |||
| // Check if new owner has repository with same name. | |||
| @@ -948,9 +959,14 @@ func DeleteRepository(uid, repoId int64, userName string) error { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| // Remove repository files. | |||
| if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| desc := fmt.Sprintf("Fail to delete repository files(%s/%s): %v", userName, repo.Name, err) | |||
| log.Warn(desc) | |||
| if err = CreateRepositoryNotice(desc); err != nil { | |||
| log.Error(4, "Fail to add notice: %v", err) | |||
| } | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| @@ -106,7 +106,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||
| if err = CommitRepoAction(userId, ru.Id, userName, actEmail, | |||
| repos.Id, repoUserName, repoName, refName, commit, oldCommitId, newCommitId); err != nil { | |||
| log.GitLogger.Fatal(4, "runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) | |||
| log.GitLogger.Fatal(4, "CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) | |||
| } | |||
| return err | |||
| } | |||
| @@ -116,8 +116,8 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||
| return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err) | |||
| } | |||
| // Push new branch. | |||
| var l *list.List | |||
| // if a new branch | |||
| if isNew { | |||
| l, err = newCommit.CommitsBefore() | |||
| if err != nil { | |||
| @@ -134,7 +134,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||
| return fmt.Errorf("runUpdate.Commit repoId: %v", err) | |||
| } | |||
| // if commits push | |||
| // Push commits. | |||
| commits := make([]*base.PushCommit, 0) | |||
| var actEmail string | |||
| for e := l.Front(); e != nil; e = e.Next() { | |||
| @@ -153,9 +153,8 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||
| } | |||
| } | |||
| //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()}) | |||
| if err = CommitRepoAction(userId, ru.Id, userName, actEmail, | |||
| repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}, oldCommitId, newCommitId); err != nil { | |||
| repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits, ""}, oldCommitId, newCommitId); err != nil { | |||
| return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) | |||
| } | |||
| return nil | |||
| @@ -488,7 +488,7 @@ func GetUserByName(name string) (*User, error) { | |||
| return user, nil | |||
| } | |||
| // GetUserEmailsByNames returns a slice of e-mails corresponds to names. | |||
| // GetUserEmailsByNames returns a list of e-mails corresponds to names. | |||
| func GetUserEmailsByNames(names []string) []string { | |||
| mails := make([]string, 0, len(names)) | |||
| for _, name := range names { | |||
| @@ -235,8 +235,22 @@ func UpdateHookTask(t *HookTask) error { | |||
| return err | |||
| } | |||
| var ( | |||
| // Prevent duplicate deliveries. | |||
| // This happens with massive hook tasks cannot finish delivering | |||
| // before next shooting starts. | |||
| isShooting = false | |||
| ) | |||
| // DeliverHooks checks and delivers undelivered hooks. | |||
| // FIXME: maybe can use goroutine to shoot a number of them at same time? | |||
| func DeliverHooks() { | |||
| if isShooting { | |||
| return | |||
| } | |||
| isShooting = true | |||
| defer func() { isShooting = false }() | |||
| tasks := make([]*HookTask, 0, 10) | |||
| timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second | |||
| x.Where("is_delivered=?", false).Iterate(new(HookTask), | |||
| @@ -255,7 +269,7 @@ func DeliverHooks() { | |||
| t.IsDelivered = true | |||
| // TODO: record response. | |||
| // FIXME: record response. | |||
| switch t.Type { | |||
| case GOGS: | |||
| { | |||
| @@ -102,7 +102,7 @@ func (f *NewSlackHookForm) Validate(ctx *macaron.Context, errs *binding.Errors, | |||
| // \/ \/ \/ | |||
| type CreateIssueForm struct { | |||
| IssueName string `form:"title" binding:"Required;MaxSize(50)"` | |||
| IssueName string `form:"title" binding:"Required;MaxSize(255)"` | |||
| MilestoneId int64 `form:"milestoneid"` | |||
| AssigneeId int64 `form:"assigneeid"` | |||
| Labels string `form:"labels"` | |||
| @@ -13,7 +13,8 @@ import ( | |||
| "regexp" | |||
| "strings" | |||
| "github.com/gogits/gfm" | |||
| "github.com/russross/blackfriday" | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| @@ -74,7 +75,7 @@ func IsReadmeFile(name string) bool { | |||
| } | |||
| type CustomRender struct { | |||
| gfm.Renderer | |||
| blackfriday.Renderer | |||
| urlPrefix string | |||
| } | |||
| @@ -154,39 +155,40 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte { | |||
| func RenderRawMarkdown(body []byte, urlPrefix string) []byte { | |||
| htmlFlags := 0 | |||
| // htmlFlags |= gfm.HTML_USE_XHTML | |||
| // htmlFlags |= gfm.HTML_USE_SMARTYPANTS | |||
| // htmlFlags |= gfm.HTML_SMARTYPANTS_FRACTIONS | |||
| // htmlFlags |= gfm.HTML_SMARTYPANTS_LATEX_DASHES | |||
| // htmlFlags |= gfm.HTML_SKIP_HTML | |||
| htmlFlags |= gfm.HTML_SKIP_STYLE | |||
| htmlFlags |= gfm.HTML_SKIP_SCRIPT | |||
| htmlFlags |= gfm.HTML_GITHUB_BLOCKCODE | |||
| htmlFlags |= gfm.HTML_OMIT_CONTENTS | |||
| // htmlFlags |= gfm.HTML_COMPLETE_PAGE | |||
| // htmlFlags |= blackfriday.HTML_USE_XHTML | |||
| // htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS | |||
| // htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS | |||
| // htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES | |||
| // htmlFlags |= blackfriday.HTML_SKIP_HTML | |||
| htmlFlags |= blackfriday.HTML_SKIP_STYLE | |||
| // htmlFlags |= blackfriday.HTML_SKIP_SCRIPT | |||
| // htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE | |||
| htmlFlags |= blackfriday.HTML_OMIT_CONTENTS | |||
| // htmlFlags |= blackfriday.HTML_COMPLETE_PAGE | |||
| renderer := &CustomRender{ | |||
| Renderer: gfm.HtmlRenderer(htmlFlags, "", ""), | |||
| Renderer: blackfriday.HtmlRenderer(htmlFlags, "", ""), | |||
| urlPrefix: urlPrefix, | |||
| } | |||
| // set up the parser | |||
| extensions := 0 | |||
| extensions |= gfm.EXTENSION_NO_INTRA_EMPHASIS | |||
| extensions |= gfm.EXTENSION_TABLES | |||
| extensions |= gfm.EXTENSION_FENCED_CODE | |||
| extensions |= gfm.EXTENSION_AUTOLINK | |||
| extensions |= gfm.EXTENSION_STRIKETHROUGH | |||
| extensions |= gfm.EXTENSION_HARD_LINE_BREAK | |||
| extensions |= gfm.EXTENSION_SPACE_HEADERS | |||
| extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | |||
| body = gfm.Markdown(body, renderer, extensions) | |||
| extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS | |||
| extensions |= blackfriday.EXTENSION_TABLES | |||
| extensions |= blackfriday.EXTENSION_FENCED_CODE | |||
| extensions |= blackfriday.EXTENSION_AUTOLINK | |||
| extensions |= blackfriday.EXTENSION_STRIKETHROUGH | |||
| extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK | |||
| extensions |= blackfriday.EXTENSION_SPACE_HEADERS | |||
| extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | |||
| body = blackfriday.Markdown(body, renderer, extensions) | |||
| return body | |||
| } | |||
| func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | |||
| body := RenderSpecialLink(rawBytes, urlPrefix) | |||
| body = RenderRawMarkdown(body, urlPrefix) | |||
| body = XSS(body) | |||
| return body | |||
| } | |||
| @@ -5,7 +5,6 @@ | |||
| package base | |||
| import ( | |||
| "bytes" | |||
| "container/list" | |||
| "encoding/json" | |||
| "errors" | |||
| @@ -107,7 +106,6 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ | |||
| return a + b | |||
| }, | |||
| "ActionIcon": ActionIcon, | |||
| "ActionDesc": ActionDesc, | |||
| "DateFormat": DateFormat, | |||
| "List": List, | |||
| "Mail2Domain": func(mail string) string { | |||
| @@ -162,19 +160,6 @@ func ActionIcon(opType int) string { | |||
| } | |||
| } | |||
| // FIXME: Legacy | |||
| const ( | |||
| TPL_CREATE_REPO = `<a href="%s/user/%s">%s</a> created repository <a href="%s">%s</a>` | |||
| TPL_COMMIT_REPO = `<a href="%s/user/%s">%s</a> pushed to <a href="%s/src/%s">%s</a> at <a href="%s">%s</a>%s` | |||
| TPL_COMMIT_REPO_LI = `<div><img src="%s?s=16" alt="user-avatar"/> <a href="%s/commit/%s" rel="nofollow">%s</a> %s</div>` | |||
| TPL_CREATE_ISSUE = `<a href="%s/user/%s">%s</a> opened issue <a href="%s/issues/%s">%s#%s</a> | |||
| <div><img src="%s?s=16" alt="user-avatar"/> %s</div>` | |||
| TPL_TRANSFER_REPO = `<a href="%s/user/%s">%s</a> transfered repository <code>%s</code> to <a href="%s">%s</a>` | |||
| TPL_PUSH_TAG = `<a href="%s/user/%s">%s</a> pushed tag <a href="%s/src/%s" rel="nofollow">%s</a> at <a href="%s">%s</a>` | |||
| TPL_COMMENT_ISSUE = `<a href="%s/user/%s">%s</a> commented on issue <a href="%s/issues/%s">%s#%s</a> | |||
| <div><img src="%s?s=16" alt="user-avatar"/> %s</div>` | |||
| ) | |||
| type PushCommit struct { | |||
| Sha1 string | |||
| Message string | |||
| @@ -183,8 +168,9 @@ type PushCommit struct { | |||
| } | |||
| type PushCommits struct { | |||
| Len int | |||
| Commits []*PushCommit | |||
| Len int | |||
| Commits []*PushCommit | |||
| CompareUrl string | |||
| } | |||
| func ActionContent2Commits(act Actioner) *PushCommits { | |||
| @@ -195,52 +181,6 @@ func ActionContent2Commits(act Actioner) *PushCommits { | |||
| return push | |||
| } | |||
| // FIXME: Legacy | |||
| // ActionDesc accepts int that represents action operation type | |||
| // and returns the description. | |||
| func ActionDesc(act Actioner) string { | |||
| actUserName := act.GetActUserName() | |||
| email := act.GetActEmail() | |||
| repoUserName := act.GetRepoUserName() | |||
| repoName := act.GetRepoName() | |||
| repoLink := repoUserName + "/" + repoName | |||
| branch := act.GetBranch() | |||
| content := act.GetContent() | |||
| switch act.GetOpType() { | |||
| case 1: // Create repository. | |||
| return fmt.Sprintf(TPL_CREATE_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, repoName) | |||
| case 5: // Commit repository. | |||
| var push *PushCommits | |||
| if err := json.Unmarshal([]byte(content), &push); err != nil { | |||
| return err.Error() | |||
| } | |||
| buf := bytes.NewBuffer([]byte("\n")) | |||
| for _, commit := range push.Commits { | |||
| buf.WriteString(fmt.Sprintf(TPL_COMMIT_REPO_LI, AvatarLink(commit.AuthorEmail), repoLink, commit.Sha1, commit.Sha1[:7], commit.Message) + "\n") | |||
| } | |||
| if push.Len > 3 { | |||
| buf.WriteString(fmt.Sprintf(`<div><a href="{{AppRootSubUrl}}/%s/%s/commits/%s" rel="nofollow">%d other commits >></a></div>`, actUserName, repoName, branch, push.Len)) | |||
| } | |||
| return fmt.Sprintf(TPL_COMMIT_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink, | |||
| buf.String()) | |||
| case 6: // Create issue. | |||
| infos := strings.SplitN(content, "|", 2) | |||
| return fmt.Sprintf(TPL_CREATE_ISSUE, setting.AppSubUrl, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0], | |||
| AvatarLink(email), infos[1]) | |||
| case 8: // Transfer repository. | |||
| newRepoLink := content + "/" + repoName | |||
| return fmt.Sprintf(TPL_TRANSFER_REPO, setting.AppSubUrl, actUserName, actUserName, repoLink, newRepoLink, newRepoLink) | |||
| case 9: // Push tag. | |||
| return fmt.Sprintf(TPL_PUSH_TAG, setting.AppSubUrl, actUserName, actUserName, repoLink, branch, branch, repoLink, repoLink) | |||
| case 10: // Comment issue. | |||
| infos := strings.SplitN(content, "|", 2) | |||
| return fmt.Sprintf(TPL_COMMENT_ISSUE, setting.AppSubUrl, actUserName, actUserName, repoLink, infos[0], repoLink, infos[0], | |||
| AvatarLink(email), infos[1]) | |||
| default: | |||
| return "invalid type" | |||
| } | |||
| } | |||
| func DiffTypeToStr(diffType int) string { | |||
| diffTypes := map[int]string{ | |||
| 1: "add", 2: "modify", 3: "del", | |||
| @@ -14,6 +14,7 @@ import ( | |||
| "hash" | |||
| "html/template" | |||
| "math" | |||
| "regexp" | |||
| "strings" | |||
| "time" | |||
| @@ -446,3 +447,29 @@ func DateFormat(t time.Time, format string) string { | |||
| format = replacer.Replace(format) | |||
| return t.Format(format) | |||
| } | |||
| type xssFilter struct { | |||
| reg *regexp.Regexp | |||
| repl []byte | |||
| } | |||
| var ( | |||
| whiteSpace = []byte(" ") | |||
| xssFilters = []xssFilter{ | |||
| {regexp.MustCompile(`\ [ONon]\w*=["]*`), whiteSpace}, | |||
| {regexp.MustCompile(`<[SCRIPTscript]{6}`), whiteSpace}, | |||
| {regexp.MustCompile(`=[` + "`" + `'"]*[JAVASCRIPTjavascript \t\0
]*:`), whiteSpace}, | |||
| } | |||
| ) | |||
| // XSS goes through all the XSS filters to make user input content as safe as possible. | |||
| func XSS(in []byte) []byte { | |||
| for _, filter := range xssFilters { | |||
| in = filter.reg.ReplaceAll(in, filter.repl) | |||
| } | |||
| return in | |||
| } | |||
| func XSSString(in string) string { | |||
| return string(XSS([]byte(in))) | |||
| } | |||
| @@ -0,0 +1,111 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package git | |||
| import ( | |||
| "errors" | |||
| "io/ioutil" | |||
| "os" | |||
| "path" | |||
| "strings" | |||
| ) | |||
| // hookNames is a list of Git hooks' name that are supported. | |||
| var hookNames = []string{ | |||
| "pre-applypatch", | |||
| "applypatch-msg", | |||
| "prepare-commit-msg", | |||
| "commit-msg", | |||
| "pre-commit", | |||
| "pre-rebase", | |||
| "post-commit", | |||
| "post-receive", | |||
| "post-update", | |||
| } | |||
| var ( | |||
| ErrNotValidHook = errors.New("not a valid Git hook") | |||
| ) | |||
| // IsValidHookName returns true if given name is a valid Git hook. | |||
| func IsValidHookName(name string) bool { | |||
| for _, hn := range hookNames { | |||
| if hn == name { | |||
| return true | |||
| } | |||
| } | |||
| return false | |||
| } | |||
| // Hook represents a Git hook. | |||
| type Hook struct { | |||
| name string | |||
| IsActive bool // Indicates whether repository has this hook. | |||
| Content string // Content of hook if it's active. | |||
| Sample string // Sample content from Git. | |||
| path string // Hook file path. | |||
| } | |||
| // GetHook returns a Git hook by given name and repository. | |||
| func GetHook(repoPath, name string) (*Hook, error) { | |||
| if !IsValidHookName(name) { | |||
| return nil, ErrNotValidHook | |||
| } | |||
| h := &Hook{ | |||
| name: name, | |||
| path: path.Join(repoPath, "hooks", name), | |||
| } | |||
| if isFile(h.path) { | |||
| data, err := ioutil.ReadFile(h.path) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| h.IsActive = true | |||
| h.Content = string(data) | |||
| } else if isFile(h.path + ".sample") { | |||
| data, err := ioutil.ReadFile(h.path + ".sample") | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| h.Sample = string(data) | |||
| } | |||
| return h, nil | |||
| } | |||
| func (h *Hook) Name() string { | |||
| return h.name | |||
| } | |||
| // Update updates hook settings. | |||
| func (h *Hook) Update() error { | |||
| if len(strings.TrimSpace(h.Content)) == 0 { | |||
| return os.Remove(h.path) | |||
| } | |||
| return ioutil.WriteFile(h.path, []byte(strings.Replace(h.Content, "\r", "", -1)), os.ModePerm) | |||
| } | |||
| // ListHooks returns a list of Git hooks of given repository. | |||
| func ListHooks(repoPath string) (_ []*Hook, err error) { | |||
| if !isDir(path.Join(repoPath, "hooks")) { | |||
| return nil, errors.New("hooks path does not exist") | |||
| } | |||
| hooks := make([]*Hook, len(hookNames)) | |||
| for i, name := range hookNames { | |||
| hooks[i], err = GetHook(repoPath, name) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| } | |||
| return hooks, nil | |||
| } | |||
| func (repo *Repository) GetHook(name string) (*Hook, error) { | |||
| return GetHook(repo.Path, name) | |||
| } | |||
| func (repo *Repository) Hooks() ([]*Hook, error) { | |||
| return ListHooks(repo.Path) | |||
| } | |||
| @@ -22,6 +22,9 @@ func (repo *Repository) IsTagExist(tagName string) bool { | |||
| // GetTags returns all tags of given repository. | |||
| func (repo *Repository) GetTags() ([]string, error) { | |||
| if gitVer.AtLeast(MustParseVersion("2.0.0")) { | |||
| return repo.getTagsReversed() | |||
| } | |||
| stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l") | |||
| if err != nil { | |||
| return nil, errors.New(stderr) | |||
| @@ -30,6 +33,15 @@ func (repo *Repository) GetTags() ([]string, error) { | |||
| return tags[:len(tags)-1], nil | |||
| } | |||
| func (repo *Repository) getTagsReversed() ([]string, error) { | |||
| stdout, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", "-l", "--sort=-v:refname") | |||
| if err != nil { | |||
| return nil, errors.New(stderr) | |||
| } | |||
| tags := strings.Split(stdout, "\n") | |||
| return tags[:len(tags)-1], nil | |||
| } | |||
| func (repo *Repository) CreateTag(tagName, idStr string) error { | |||
| _, stderr, err := com.ExecCmdDir(repo.Path, "git", "tag", tagName, idStr) | |||
| if err != nil { | |||
| @@ -7,6 +7,7 @@ package git | |||
| import ( | |||
| "bytes" | |||
| "container/list" | |||
| "os" | |||
| "path/filepath" | |||
| "strings" | |||
| ) | |||
| @@ -46,3 +47,23 @@ func RefEndName(refStr string) string { | |||
| func filepathFromSHA1(rootdir, sha1 string) string { | |||
| return filepath.Join(rootdir, "objects", sha1[:2], sha1[2:]) | |||
| } | |||
| // isDir returns true if given path is a directory, | |||
| // or returns false when it's a file or does not exist. | |||
| func isDir(dir string) bool { | |||
| f, e := os.Stat(dir) | |||
| if e != nil { | |||
| return false | |||
| } | |||
| return f.IsDir() | |||
| } | |||
| // isFile returns true if given path is a file, | |||
| // or returns false when it's a directory or does not exist. | |||
| func isFile(filePath string) bool { | |||
| f, e := os.Stat(filePath) | |||
| if e != nil { | |||
| return false | |||
| } | |||
| return !f.IsDir() | |||
| } | |||
| @@ -74,6 +74,10 @@ func (v *Version) LessThan(that *Version) bool { | |||
| return v.Compare(that) < 0 | |||
| } | |||
| func (v *Version) AtLeast(that *Version) bool { | |||
| return v.Compare(that) >= 0 | |||
| } | |||
| // GetVersion returns current Git version installed. | |||
| func GetVersion() (*Version, error) { | |||
| if gitVer != nil { | |||
| @@ -5,7 +5,9 @@ | |||
| package mailer | |||
| import ( | |||
| "crypto/tls" | |||
| "fmt" | |||
| "net" | |||
| "net/smtp" | |||
| "strings" | |||
| @@ -33,7 +35,7 @@ func (m Message) Content() string { | |||
| } | |||
| // create mail content | |||
| content := "From: " + m.From + "<" + m.User + | |||
| content := "From: \"" + m.From + "\" <" + m.User + | |||
| ">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body | |||
| return content | |||
| } | |||
| @@ -64,6 +66,53 @@ func processMailQueue() { | |||
| } | |||
| } | |||
| // sendMail allows mail with self-signed certificates. | |||
| func sendMail(hostAddressWithPort string, auth smtp.Auth, from string, recipients []string, msgContent []byte) error { | |||
| client, err := smtp.Dial(hostAddressWithPort) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| host, _, _ := net.SplitHostPort(hostAddressWithPort) | |||
| tlsConn := &tls.Config{ | |||
| InsecureSkipVerify: true, | |||
| ServerName: host, | |||
| } | |||
| if err = client.StartTLS(tlsConn); err != nil { | |||
| return err | |||
| } | |||
| if auth != nil { | |||
| if err = client.Auth(auth); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| if err = client.Mail(from); err != nil { | |||
| return err | |||
| } | |||
| for _, rec := range recipients { | |||
| if err = client.Rcpt(rec); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| w, err := client.Data() | |||
| if err != nil { | |||
| return err | |||
| } | |||
| if _, err = w.Write([]byte(msgContent)); err != nil { | |||
| return err | |||
| } | |||
| if err = w.Close(); err != nil { | |||
| return err | |||
| } | |||
| return client.Quit() | |||
| } | |||
| // Direct Send mail message | |||
| func Send(msg *Message) (int, error) { | |||
| log.Trace("Sending mails to: %s", strings.Join(msg.To, "; ")) | |||
| @@ -85,7 +134,7 @@ func Send(msg *Message) (int, error) { | |||
| num := 0 | |||
| for _, to := range msg.To { | |||
| body := []byte("To: " + to + "\r\n" + content) | |||
| err := smtp.SendMail(setting.MailService.Host, auth, msg.From, []string{to}, body) | |||
| err := sendMail(setting.MailService.Host, auth, msg.From, []string{to}, body) | |||
| if err != nil { | |||
| return num, err | |||
| } | |||
| @@ -96,7 +145,7 @@ func Send(msg *Message) (int, error) { | |||
| body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content) | |||
| // send to multiple emails in one message | |||
| err := smtp.SendMail(setting.MailService.Host, auth, msg.From, msg.To, body) | |||
| err := sendMail(setting.MailService.Host, auth, msg.From, msg.To, body) | |||
| if err != nil { | |||
| return 0, err | |||
| } else { | |||
| @@ -29,7 +29,6 @@ import ( | |||
| // Context represents context of a request. | |||
| type Context struct { | |||
| *macaron.Context | |||
| i18n.Locale | |||
| Cache cache.Cache | |||
| csrf csrf.CSRF | |||
| Flash *session.Flash | |||
| @@ -76,12 +75,6 @@ type Context struct { | |||
| } | |||
| } | |||
| // Query querys form parameter. | |||
| func (ctx *Context) Query(name string) string { | |||
| ctx.Req.ParseForm() | |||
| return ctx.Req.Form.Get(name) | |||
| } | |||
| // HasError returns true if error occurs in form validation. | |||
| func (ctx *Context) HasApiError() bool { | |||
| hasErr, ok := ctx.Data["HasError"] | |||
| @@ -162,7 +155,6 @@ func Contexter() macaron.Handler { | |||
| return func(c *macaron.Context, l i18n.Locale, cache cache.Cache, sess session.Store, f *session.Flash, x csrf.CSRF) { | |||
| ctx := &Context{ | |||
| Context: c, | |||
| Locale: l, | |||
| Cache: cache, | |||
| csrf: x, | |||
| Flash: f, | |||
| @@ -308,3 +308,13 @@ func RequireTrueOwner() macaron.Handler { | |||
| } | |||
| } | |||
| } | |||
| // GitHookService checks if repsitory Git hooks service has been enabled. | |||
| func GitHookService() macaron.Handler { | |||
| return func(ctx *Context) { | |||
| if !setting.Service.EnableGitHooks { | |||
| ctx.Handle(404, "GitHookService", nil) | |||
| return | |||
| } | |||
| } | |||
| } | |||
| @@ -275,6 +275,7 @@ var Service struct { | |||
| LdapAuth bool | |||
| ActiveCodeLives int | |||
| ResetPwdCodeLives int | |||
| EnableGitHooks bool | |||
| } | |||
| func newService() { | |||
| @@ -284,6 +285,7 @@ func newService() { | |||
| Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW") | |||
| Service.EnableCacheAvatar = Cfg.MustBool("service", "ENABLE_CACHE_AVATAR") | |||
| Service.EnableReverseProxyAuth = Cfg.MustBool("service", "ENABLE_REVERSE_PROXY_AUTHENTICATION") | |||
| Service.EnableGitHooks = Cfg.MustBool("service", "ENABLE_GIT_HOOKS") | |||
| } | |||
| var logLevels = map[string]string{ | |||
| @@ -88,6 +88,7 @@ img.avatar-100 { | |||
| z-index: 100; | |||
| font-size: 12px; | |||
| width: 120%; | |||
| min-width: 100px; | |||
| } | |||
| #footer-lang .drop-down li > a { | |||
| padding: 3px 9px; | |||
| @@ -270,6 +271,10 @@ img.avatar-100 { | |||
| .pagination li { | |||
| display: inline; | |||
| } | |||
| .list-unstyled { | |||
| padding-left: 0; | |||
| list-style: none; | |||
| } | |||
| .markdown { | |||
| background-color: white; | |||
| font-size: 16px; | |||
| @@ -1397,12 +1402,10 @@ The register and sign-in page style | |||
| } | |||
| .code-view .lines-num span { | |||
| font-family: Monaco, Menlo, Consolas, "Courier New", monospace; | |||
| line-height: 18px; | |||
| padding: 0 8px 0 10px; | |||
| line-height: 1.6; | |||
| padding: 0 10px; | |||
| cursor: pointer; | |||
| display: block; | |||
| margin-top: 2px; | |||
| font-size: 12px; | |||
| } | |||
| .code-view .lines-code > pre { | |||
| border: none; | |||
| @@ -1486,6 +1489,106 @@ The register and sign-in page style | |||
| font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace; | |||
| font-size: 14px; | |||
| } | |||
| .diff-head-box { | |||
| margin-top: 10px; | |||
| } | |||
| .diff-head-box .panel-body { | |||
| padding: 10px 15px 5px 10px; | |||
| } | |||
| .diff-head-box .author img { | |||
| margin-top: -7px; | |||
| } | |||
| .diff-detail-box { | |||
| margin: 15px 0; | |||
| line-height: 30px; | |||
| } | |||
| .diff-detail-box ol { | |||
| clear: both; | |||
| padding-left: 0; | |||
| margin-bottom: 28px; | |||
| } | |||
| .diff-detail-box ol li { | |||
| list-style: none; | |||
| padding-bottom: 4px; | |||
| margin-bottom: 4px; | |||
| border-bottom: 1px dashed #DDD; | |||
| padding-left: 6px; | |||
| } | |||
| .diff-detail-box span.status { | |||
| display: inline-block; | |||
| width: 12px; | |||
| height: 12px; | |||
| margin-right: 8px; | |||
| vertical-align: middle; | |||
| } | |||
| .diff-detail-box span.status.modify { | |||
| background-color: #f0db88; | |||
| } | |||
| .diff-detail-box span.status.add { | |||
| background-color: #b4e2b4; | |||
| } | |||
| .diff-detail-box span.status.del { | |||
| background-color: #e9aeae; | |||
| } | |||
| .diff-detail-box span.status.rename { | |||
| background-color: #dad8ff; | |||
| } | |||
| .diff-box .count { | |||
| margin-right: 12px; | |||
| } | |||
| .diff-box .count .bar { | |||
| background-color: #e75316; | |||
| height: 12px; | |||
| width: 40px; | |||
| display: inline-block; | |||
| margin: 2px 4px 0 4px; | |||
| vertical-align: text-top; | |||
| } | |||
| .diff-box .count .bar .add { | |||
| background-color: #77c64a; | |||
| height: 12px; | |||
| } | |||
| .diff-box .file { | |||
| color: #888; | |||
| } | |||
| .diff-box .panel-header { | |||
| font-size: 14px; | |||
| } | |||
| .diff-file-box .code-diff tbody tr:hover td, | |||
| .diff-file-box .code-diff tbody tr:hover pre { | |||
| background-color: #FFF8D2 !important; | |||
| border-color: #F0DB88 !important; | |||
| } | |||
| .diff-file-box .file-body.file-code .lines-num-old { | |||
| border-right: 1px solid #DDD; | |||
| } | |||
| .file-content .file-body.file-code .lines-num { | |||
| text-align: right; | |||
| color: #999; | |||
| background: #fafafa; | |||
| width: 1%; | |||
| } | |||
| .diff-file-box .code-diff tbody tr.tag-code td, | |||
| .diff-file-box .code-diff tbody tr.tag-code pre { | |||
| background-color: #E0E0E0 !important; | |||
| border-color: #ADADAD !important; | |||
| } | |||
| .diff-file-box .code-diff tbody tr.del-code td, | |||
| .diff-file-box .code-diff tbody tr.del-code pre { | |||
| background-color: #ffe2dd !important; | |||
| border-color: #e9aeae !important; | |||
| } | |||
| .diff-file-box .code-diff tbody tr.add-code td, | |||
| .diff-file-box .code-diff tbody tr.add-code pre { | |||
| background-color: #d1ffd6 !important; | |||
| border-color: #b4e2b4 !important; | |||
| } | |||
| .compare-head-box { | |||
| margin-top: 10px; | |||
| } | |||
| .compare-head-box .compare { | |||
| padding: 0 15px 15px 15px; | |||
| } | |||
| #admin-wrapper, | |||
| #setting-wrapper { | |||
| padding-bottom: 100px; | |||
| @@ -366,6 +366,9 @@ dt { | |||
| .grid-4-5 { | |||
| width: 80%; | |||
| } | |||
| .btn { | |||
| white-space: nowrap; | |||
| } | |||
| .btn-small { | |||
| font-size: 10.8px; | |||
| padding: .4em .9em; | |||
| @@ -457,6 +460,9 @@ dt { | |||
| box-sizing: content-box; | |||
| text-align: center; | |||
| } | |||
| .btn-comb { | |||
| margin-left: -1px; | |||
| } | |||
| .btn-disabled { | |||
| opacity: .6; | |||
| cursor: not-allowed; | |||
| @@ -480,6 +486,10 @@ dt { | |||
| .ipt-large { | |||
| font-size: 14.4px; | |||
| } | |||
| .ipt-textarea { | |||
| height: auto !important; | |||
| width: auto; | |||
| } | |||
| .ipt-disabled, | |||
| input[disabled] { | |||
| background-color: #f2f2f2 !important; | |||
| @@ -709,6 +719,14 @@ ul.menu-radius > li:last-child > a { | |||
| border-bottom-left-radius: .3em; | |||
| border-bottom-right-radius: .3em; | |||
| } | |||
| .panel.panel-info { | |||
| border-color: #85c5e5; | |||
| } | |||
| .panel.panel-info > .panel-header { | |||
| color: #31708f; | |||
| background-color: #d9edf7; | |||
| border-color: #85c5e5; | |||
| } | |||
| .panel.panel-warning { | |||
| border-color: #F0C36D; | |||
| } | |||
| @@ -299,6 +299,9 @@ function initCore() { | |||
| e.preventDefault(); | |||
| $.magnificPopup.close(); | |||
| }); | |||
| // Collapse. | |||
| $('.collapse').hide(); | |||
| } | |||
| function initUserSetting() { | |||
| @@ -698,6 +701,37 @@ function initProfile() { | |||
| }); | |||
| } | |||
| function initTimeSwitch() { | |||
| // Time switch. | |||
| $(".time-since[title]").on("click", function () { | |||
| var $this = $(this); | |||
| var title = $this.attr("title"); | |||
| var text = $this.text(); | |||
| $this.text(title); | |||
| $this.attr("title", text); | |||
| }); | |||
| } | |||
| function initDiff() { | |||
| $('.diff-detail-box>a').click(function () { | |||
| $($(this).data('target')).slideToggle(100); | |||
| }) | |||
| var $counter = $('.diff-counter'); | |||
| if ($counter.length < 1) { | |||
| return; | |||
| } | |||
| $counter.each(function (i, item) { | |||
| var $item = $(item); | |||
| var addLine = $item.find('span[data-line].add').data("line"); | |||
| var delLine = $item.find('span[data-line].del').data("line"); | |||
| var addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100; | |||
| $item.find(".bar .add").css("width", addPercent + "%"); | |||
| }); | |||
| } | |||
| $(document).ready(function () { | |||
| Gogs.AppSubUrl = $('head').data('suburl') || ''; | |||
| initCore(); | |||
| @@ -737,6 +771,10 @@ $(document).ready(function () { | |||
| if ($('#user-profile-page').length) { | |||
| initProfile(); | |||
| } | |||
| if ($('#diff-page').length) { | |||
| initTimeSwitch(); | |||
| initDiff(); | |||
| } | |||
| $('#dashboard-sidebar-menu').tabs(); | |||
| $('#pull-issue-preview').markdown_preview(".issue-add-comment"); | |||
| @@ -102,6 +102,7 @@ clear: both; | |||
| z-index: 100; | |||
| font-size: 12px; | |||
| width: 120%; | |||
| min-width: 100px; | |||
| li > a { | |||
| padding: 3px 9px; | |||
| } | |||
| @@ -290,4 +291,8 @@ clear: both; | |||
| li { | |||
| display: inline; | |||
| } | |||
| } | |||
| .list-unstyled { | |||
| padding-left: 0; | |||
| list-style: none; | |||
| } | |||
| @@ -444,13 +444,11 @@ | |||
| background: #f5f5f5; | |||
| width: 1%; | |||
| span { | |||
| font-family: Monaco, Menlo, Consolas, "Courier New", monospace; | |||
| line-height: 18px; | |||
| padding: 0 8px 0 10px; | |||
| cursor: pointer; | |||
| display: block; | |||
| margin-top: 2px; | |||
| font-size: 12px; | |||
| font-family: Monaco,Menlo,Consolas,"Courier New",monospace; | |||
| line-height: 1.6; | |||
| padding: 0 10px; | |||
| cursor: pointer; | |||
| display: block; | |||
| } | |||
| } | |||
| .lines-code > pre { | |||
| @@ -494,37 +492,138 @@ | |||
| } | |||
| } | |||
| .repo-user-list-block { | |||
| position: relative; | |||
| top: 5px; | |||
| position: relative; | |||
| top: 5px; | |||
| } | |||
| .setting-list { | |||
| width: 100%; | |||
| list-style: none; | |||
| width: 100%; | |||
| list-style: none; | |||
| } | |||
| #commits-list { | |||
| padding-top: 20px; | |||
| h4{ | |||
| line-height: 30px; | |||
| margin-bottom: 0; | |||
| } | |||
| padding-top: 20px; | |||
| h4{ | |||
| line-height: 30px; | |||
| margin-bottom: 0; | |||
| } | |||
| } | |||
| .commit-list { | |||
| th { | |||
| background-color: #FFF; | |||
| line-height: 28px !important; | |||
| } | |||
| .date { | |||
| width: 120px; | |||
| } | |||
| .author { | |||
| padding-left: 20px; | |||
| min-width: 180px; | |||
| img { | |||
| margin-top: -4px; | |||
| th { | |||
| background-color: #FFF; | |||
| line-height: 28px !important; | |||
| } | |||
| .date { | |||
| width: 120px; | |||
| } | |||
| .author { | |||
| padding-left: 20px; | |||
| min-width: 180px; | |||
| img { | |||
| margin-top: -4px; | |||
| } | |||
| } | |||
| .sha a { | |||
| font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace; | |||
| font-size: 14px; | |||
| } | |||
| } | |||
| .diff-head-box { | |||
| margin-top: 10px; | |||
| .panel-body { | |||
| padding: 10px 15px 5px 10px; | |||
| } | |||
| .author { | |||
| img { | |||
| margin-top: -7px; | |||
| } | |||
| } | |||
| } | |||
| .diff-detail-box { | |||
| margin: 15px 0; | |||
| line-height: 30px; | |||
| ol { | |||
| clear: both; | |||
| padding-left: 0; | |||
| margin-bottom: 28px; | |||
| li { | |||
| list-style: none; | |||
| padding-bottom: 4px; | |||
| margin-bottom: 4px; | |||
| border-bottom: 1px dashed #DDD; | |||
| padding-left: 6px; | |||
| } | |||
| } | |||
| span.status{ | |||
| display: inline-block; | |||
| width: 12px; | |||
| height: 12px; | |||
| margin-right: 8px; | |||
| vertical-align: middle; | |||
| &.modify { | |||
| background-color: #f0db88; | |||
| } | |||
| &.add { | |||
| background-color: #b4e2b4; | |||
| } | |||
| &.del { | |||
| background-color: #e9aeae; | |||
| } | |||
| &.rename { | |||
| background-color: #dad8ff; | |||
| } | |||
| } | |||
| } | |||
| .diff-box { | |||
| .count { | |||
| margin-right: 12px; | |||
| .bar { | |||
| background-color: #e75316; | |||
| height: 12px; | |||
| width: 40px; | |||
| display: inline-block; | |||
| margin: 2px 4px 0 4px; | |||
| vertical-align: text-top; | |||
| .add { | |||
| background-color: #77c64a; | |||
| height: 12px; | |||
| } | |||
| } | |||
| } | |||
| .file { | |||
| color: #888; | |||
| } | |||
| .panel-header { | |||
| font-size: 14px; | |||
| } | |||
| } | |||
| .diff-file-box .code-diff tbody tr:hover td, .diff-file-box .code-diff tbody tr:hover pre { | |||
| background-color: #FFF8D2 !important; | |||
| border-color: #F0DB88 !important; | |||
| } | |||
| .diff-file-box .file-body.file-code .lines-num-old { | |||
| border-right: 1px solid #DDD; | |||
| } | |||
| .file-content .file-body.file-code .lines-num { | |||
| text-align: right; | |||
| color: #999; | |||
| background: #fafafa; | |||
| width: 1%; | |||
| } | |||
| .diff-file-box .code-diff tbody tr.tag-code td, .diff-file-box .code-diff tbody tr.tag-code pre { | |||
| background-color: #E0E0E0 !important; | |||
| border-color: #ADADAD !important; | |||
| } | |||
| .diff-file-box .code-diff tbody tr.del-code td, .diff-file-box .code-diff tbody tr.del-code pre { | |||
| background-color: #ffe2dd !important; | |||
| border-color: #e9aeae !important; | |||
| } | |||
| .diff-file-box .code-diff tbody tr.add-code td, .diff-file-box .code-diff tbody tr.add-code pre { | |||
| background-color: #d1ffd6 !important; | |||
| border-color: #b4e2b4 !important; | |||
| } | |||
| .compare-head-box { | |||
| margin-top: 10px; | |||
| .compare { | |||
| padding: 0 15px 15px 15px; | |||
| } | |||
| } | |||
| .sha a { | |||
| font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace; | |||
| font-size: 14px; | |||
| } | |||
| } | |||
| @@ -1,9 +1,8 @@ | |||
| @import "var"; | |||
| // colored buttons | |||
| // Button. | |||
| .btn { | |||
| &:hover { | |||
| } | |||
| white-space: nowrap; | |||
| } | |||
| .btn-small { | |||
| font-size: 0.9*@baseFontSize; | |||
| @@ -102,6 +101,9 @@ | |||
| box-sizing: content-box; | |||
| text-align: center; | |||
| } | |||
| .btn-comb { | |||
| margin-left: -1px; | |||
| } | |||
| .btn-disabled { | |||
| opacity: .6; | |||
| @@ -116,25 +118,24 @@ | |||
| } | |||
| // input form elements | |||
| .ipt { | |||
| &:focus { | |||
| border-color: @iptFocusBorderColor; | |||
| } | |||
| &:focus { | |||
| border-color: @iptFocusBorderColor; | |||
| } | |||
| } | |||
| .ipt-radius { | |||
| border-radius: .25em; | |||
| border-radius: .25em; | |||
| } | |||
| .ipt-small { | |||
| font-size: .8*@baseFontSize; | |||
| font-size: .8*@baseFontSize; | |||
| } | |||
| .ipt-large { | |||
| font-size: 1.2*@baseFontSize; | |||
| font-size: 1.2*@baseFontSize; | |||
| } | |||
| .ipt-textarea { | |||
| height: auto !important; | |||
| width: auto; | |||
| } | |||
| .ipt-disabled, | |||
| input[disabled] { | |||
| background-color: @iptDisabledColor !important; | |||
| @@ -144,14 +145,12 @@ input[disabled] { | |||
| color: #888; | |||
| cursor: not-allowed; | |||
| } | |||
| .ipt-readonly, | |||
| input[readonly] { | |||
| &:focus { | |||
| background-color: @iptDisabledColor !important; | |||
| } | |||
| } | |||
| .ipt-error { | |||
| border-color: @iptErrorBorderColor !important; | |||
| background-color: @iptErrorFocusColor !important; | |||
| @@ -36,6 +36,14 @@ | |||
| border-bottom-right-radius: .3em; | |||
| } | |||
| } | |||
| &.panel-info { | |||
| border-color: #85c5e5; | |||
| > .panel-header { | |||
| color: #31708f; | |||
| background-color: #d9edf7; | |||
| border-color: #85c5e5; | |||
| } | |||
| } | |||
| &.panel-warning { | |||
| border-color: #F0C36D; | |||
| > .panel-header { | |||
| @@ -0,0 +1,46 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package admin | |||
| import ( | |||
| "github.com/Unknwon/com" | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/log" | |||
| "github.com/gogits/gogs/modules/middleware" | |||
| ) | |||
| const ( | |||
| NOTICES base.TplName = "admin/notice" | |||
| ) | |||
| func Notices(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.notices") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminNotices"] = true | |||
| pageNum := 50 | |||
| p := pagination(ctx, models.CountNotices(), pageNum) | |||
| notices, err := models.GetNotices(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetNotices", err) | |||
| return | |||
| } | |||
| ctx.Data["Notices"] = notices | |||
| ctx.HTML(200, NOTICES) | |||
| } | |||
| func DeleteNotice(ctx *middleware.Context) { | |||
| id := com.StrTo(ctx.Params(":id")).MustInt64() | |||
| if err := models.DeleteNotice(id); err != nil { | |||
| ctx.Handle(500, "DeleteNotice", err) | |||
| return | |||
| } | |||
| log.Trace("System notice deleted by admin(%s): %d", ctx.User.Name, id) | |||
| ctx.Flash.Success(ctx.Tr("admin.notices.delete_success")) | |||
| ctx.Redirect("/admin/notices") | |||
| } | |||
| @@ -25,7 +25,7 @@ func Organizations(ctx *middleware.Context) { | |||
| var err error | |||
| ctx.Data["Orgs"], err = models.GetOrganizations(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetUsers", err) | |||
| ctx.Handle(500, "GetOrganizations", err) | |||
| return | |||
| } | |||
| ctx.HTML(200, ORGS) | |||
| @@ -24,14 +24,14 @@ const ( | |||
| ) | |||
| func pagination(ctx *middleware.Context, count int64, pageNum int) int { | |||
| p := com.StrTo(ctx.Query("p")).MustInt() | |||
| p := ctx.QueryInt("p") | |||
| if p < 1 { | |||
| p = 1 | |||
| } | |||
| curCount := int64((p-1)*pageNum + pageNum) | |||
| if curCount > count { | |||
| if curCount >= count { | |||
| p = int(count) / pageNum | |||
| } else if count > curCount { | |||
| } else { | |||
| ctx.Data["NextPageNum"] = p + 1 | |||
| } | |||
| if p > 1 { | |||
| @@ -48,12 +48,12 @@ func Users(ctx *middleware.Context) { | |||
| pageNum := 50 | |||
| p := pagination(ctx, models.CountUsers(), pageNum) | |||
| var err error | |||
| ctx.Data["Users"], err = models.GetUsers(pageNum, (p-1)*pageNum) | |||
| users, err := models.GetUsers(pageNum, (p-1)*pageNum) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetUsers", err) | |||
| return | |||
| } | |||
| ctx.Data["Users"] = users | |||
| ctx.HTML(200, USERS) | |||
| } | |||
| @@ -92,7 +92,7 @@ func SettingsDelete(ctx *middleware.Context) { | |||
| ctx.Handle(500, "DeleteOrganization", err) | |||
| } | |||
| } else { | |||
| log.Trace("Organization deleted: %s", ctx.User.Name) | |||
| log.Trace("Organization deleted: %s", org.Name) | |||
| ctx.Redirect(setting.AppSubUrl + "/") | |||
| } | |||
| return | |||
| @@ -124,6 +124,11 @@ func TeamsRepoAction(ctx *middleware.Context) { | |||
| var repo *models.Repository | |||
| repo, err = models.GetRepositoryByName(ctx.Org.Organization.Id, repoName) | |||
| if err != nil { | |||
| if err == models.ErrRepoNotExist { | |||
| ctx.Flash.Error(ctx.Tr("org.teams.add_nonexistent_repo")) | |||
| ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories") | |||
| return | |||
| } | |||
| ctx.Handle(500, "GetRepositoryByName", err) | |||
| return | |||
| } | |||
| @@ -159,6 +159,7 @@ func Diff(ctx *middleware.Context) { | |||
| ctx.Data["IsImageFile"] = isImageFile | |||
| ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitId) | |||
| ctx.Data["Commit"] = commit | |||
| ctx.Data["Author"] = models.ValidateCommitWithEmail(commit) | |||
| ctx.Data["Diff"] = diff | |||
| ctx.Data["Parents"] = parents | |||
| ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 | |||
| @@ -212,6 +213,7 @@ func CompareDiff(ctx *middleware.Context) { | |||
| ctx.Handle(500, "CommitsBeforeUntil", err) | |||
| return | |||
| } | |||
| commits = models.ValidateCommitsWithEmails(commits) | |||
| ctx.Data["Commits"] = commits | |||
| ctx.Data["CommitCount"] = commits.Len() | |||
| @@ -274,13 +276,15 @@ func FileHistory(ctx *middleware.Context) { | |||
| nextPage = 0 | |||
| } | |||
| ctx.Data["Commits"], err = ctx.Repo.GitRepo.CommitsByFileAndRange( | |||
| commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange( | |||
| branchName, fileName, page) | |||
| if err != nil { | |||
| ctx.Handle(500, "repo.FileHistory(CommitsByRange)", err) | |||
| return | |||
| } | |||
| commits = models.ValidateCommitsWithEmails(commits) | |||
| ctx.Data["Commits"] = commits | |||
| ctx.Data["Username"] = userName | |||
| ctx.Data["Reponame"] = repoName | |||
| ctx.Data["FileName"] = fileName | |||
| @@ -16,6 +16,7 @@ import ( | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/auth" | |||
| "github.com/gogits/gogs/modules/base" | |||
| "github.com/gogits/gogs/modules/git" | |||
| "github.com/gogits/gogs/modules/log" | |||
| "github.com/gogits/gogs/modules/mailer" | |||
| "github.com/gogits/gogs/modules/middleware" | |||
| @@ -26,6 +27,8 @@ const ( | |||
| SETTINGS_OPTIONS base.TplName = "repo/settings/options" | |||
| COLLABORATION base.TplName = "repo/settings/collaboration" | |||
| HOOKS base.TplName = "repo/settings/hooks" | |||
| GITHOOKS base.TplName = "repo/settings/githooks" | |||
| GITHOOK_EDIT base.TplName = "repo/settings/githook_edit" | |||
| HOOK_NEW base.TplName = "repo/settings/hook_new" | |||
| ORG_HOOK_NEW base.TplName = "org/settings/hook_new" | |||
| ) | |||
| @@ -193,9 +196,16 @@ func SettingsCollaboration(ctx *middleware.Context) { | |||
| return | |||
| } | |||
| // Check if user is organization member. | |||
| if ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgMember(u.Id) { | |||
| ctx.Flash.Info(ctx.Tr("repo.settings.user_is_org_member")) | |||
| ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration") | |||
| return | |||
| } | |||
| if err = models.AddAccess(&models.Access{UserName: name, RepoName: repoLink, | |||
| Mode: models.WRITABLE}); err != nil { | |||
| ctx.Handle(500, "AddAccess2", err) | |||
| ctx.Handle(500, "AddAccess", err) | |||
| return | |||
| } | |||
| @@ -244,16 +254,20 @@ func SettingsCollaboration(ctx *middleware.Context) { | |||
| return | |||
| } | |||
| us := make([]*models.User, len(names)) | |||
| for i, name := range names { | |||
| us[i], err = models.GetUserByName(name) | |||
| collaborators := make([]*models.User, 0, len(names)) | |||
| for _, name := range names { | |||
| u, err := models.GetUserByName(name) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetUserByName", err) | |||
| return | |||
| } | |||
| // Does not show organization members. | |||
| if ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOrgMember(u.Id) { | |||
| continue | |||
| } | |||
| collaborators = append(collaborators, u) | |||
| } | |||
| ctx.Data["Collaborators"] = us | |||
| ctx.Data["Collaborators"] = collaborators | |||
| ctx.HTML(200, COLLABORATION) | |||
| } | |||
| @@ -591,3 +605,54 @@ func getOrgRepoCtx(ctx *middleware.Context) (*OrgRepoCtx, error) { | |||
| return &OrgRepoCtx{}, errors.New("Unable to set OrgRepo context") | |||
| } | |||
| } | |||
| func GitHooks(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("repo.settings") | |||
| ctx.Data["PageIsSettingsGitHooks"] = true | |||
| hooks, err := ctx.Repo.GitRepo.Hooks() | |||
| if err != nil { | |||
| ctx.Handle(500, "Hooks", err) | |||
| return | |||
| } | |||
| ctx.Data["Hooks"] = hooks | |||
| ctx.HTML(200, GITHOOKS) | |||
| } | |||
| func GitHooksEdit(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("repo.settings") | |||
| ctx.Data["PageIsSettingsGitHooks"] = true | |||
| name := ctx.Params(":name") | |||
| hook, err := ctx.Repo.GitRepo.GetHook(name) | |||
| if err != nil { | |||
| if err == git.ErrNotValidHook { | |||
| ctx.Handle(404, "GetHook", err) | |||
| } else { | |||
| ctx.Handle(500, "GetHook", err) | |||
| } | |||
| return | |||
| } | |||
| ctx.Data["Hook"] = hook | |||
| ctx.HTML(200, GITHOOK_EDIT) | |||
| } | |||
| func GitHooksEditPost(ctx *middleware.Context) { | |||
| name := ctx.Params(":name") | |||
| hook, err := ctx.Repo.GitRepo.GetHook(name) | |||
| if err != nil { | |||
| if err == git.ErrNotValidHook { | |||
| ctx.Handle(404, "GetHook", err) | |||
| } else { | |||
| ctx.Handle(500, "GetHook", err) | |||
| } | |||
| return | |||
| } | |||
| hook.Content = ctx.Query("content") | |||
| if err = hook.Update(); err != nil { | |||
| ctx.Handle(500, "hook.Update", err) | |||
| return | |||
| } | |||
| ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks/git") | |||
| } | |||
| @@ -166,7 +166,7 @@ func Home(ctx *middleware.Context) { | |||
| } | |||
| if readmeFile != nil { | |||
| ctx.Data["ReadmeInHome"] = true | |||
| ctx.Data["ReadmeInList"] = true | |||
| ctx.Data["ReadmeExist"] = true | |||
| if dataRc, err := readmeFile.Data(); err != nil { | |||
| ctx.Handle(404, "repo.SinglereadmeFile.LookupBlob", err) | |||
| @@ -177,9 +177,13 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) { | |||
| cleanContent := strings.Replace(form.Content, "\n", "", -1) | |||
| if ok, err := models.CheckPublicKeyString(cleanContent); !ok { | |||
| ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error())) | |||
| ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh") | |||
| return | |||
| if err == models.ErrKeyUnableVerify { | |||
| ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key")) | |||
| } else { | |||
| ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error())) | |||
| ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh") | |||
| return | |||
| } | |||
| } | |||
| k := &models.PublicKey{ | |||
| @@ -0,0 +1,2 @@ | |||
| #!/bin/sh | |||
| su git -c "/home/git/gogs/scripts/gogs_supervisord.sh restart" | |||
| @@ -1,10 +1,15 @@ | |||
| #!/bin/sh | |||
| echo 'plase remember to modify the command path in etc/supervisord.conf(line 23)' | |||
| PID="/tmp/supervisord.pid" | |||
| PID="log/supervisord.pid" | |||
| CONF="etc/supervisord.conf" | |||
| EXEPATH='/usr/bin/gogs_start' | |||
| if [ ! -f $EXEPATH ]; then | |||
| gogs_scripts_path=$(cd `dirname $0`; pwd) | |||
| echo $gogs_scripts_path | |||
| sudo ln -s $gogs_scripts_path'/start.sh' /usr/bin/gogs_start | |||
| fi | |||
| LOGDIR="log" | |||
| if [ ! -d $LOGDIR ]; then | |||
| mkdir $LOGDIR | |||
| @@ -1 +1 @@ | |||
| 0.5.4.1003 Beta | |||
| 0.5.5.1013 Beta | |||
| @@ -58,7 +58,7 @@ | |||
| <td>{{.Pid}}</td> | |||
| <td>{{.Description}}</td> | |||
| <td>{{.Start}}</td> | |||
| <td>{{TimeSince .Start}}</td> | |||
| <td>{{TimeSince .Start $.Lang}}</td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| @@ -8,6 +8,7 @@ | |||
| <li {{if .PageIsAdminRepositories}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/repos">{{.i18n.Tr "admin.repositories"}}</a></li> | |||
| <li {{if .PageIsAdminAuthentications}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/auths">{{.i18n.Tr "admin.authentication"}}</a></li> | |||
| <li {{if .PageIsAdminConfig}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/config">{{.i18n.Tr "admin.config"}}</a></li> | |||
| <li {{if .PageIsAdminNotices}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/notices">{{.i18n.Tr "admin.notices"}}</a></li> | |||
| <li {{if .PageIsAdminMonitor}}class="current"{{end}}><a href="{{AppSubUrl}}/admin/monitor">{{.i18n.Tr "admin.monitor"}}</a></li> | |||
| </ul> | |||
| </div> | |||
| @@ -0,0 +1,54 @@ | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="admin-wrapper"> | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="admin-setting" class="container clear"> | |||
| {{template "admin/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "admin.notices.system_notice_list"}}</strong> | |||
| </div> | |||
| <div class="panel-body admin-panel"> | |||
| <div class="admin-table"> | |||
| <table class="table table-striped"> | |||
| <thead> | |||
| <tr> | |||
| <th>Id</th> | |||
| <th>{{.i18n.Tr "admin.notices.type"}}</th> | |||
| <th>{{.i18n.Tr "admin.notices.desc"}}</th> | |||
| <th>{{.i18n.Tr "admin.users.created"}}</th> | |||
| <th>{{.i18n.Tr "admin.notices.op"}}</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{range .Notices}} | |||
| <tr> | |||
| <td>{{.Id}}</td> | |||
| <td>{{$.i18n.Tr .TrStr}}</td> | |||
| <td class="grid-1-2"><span>{{.Description}}</span></td> | |||
| <td>{{.Created}}</td> | |||
| <td><a href="{{AppSubUrl}}/admin/notices/{{.Id}}/delete"><i class="fa fa-trash-o text-red"></i></a></td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{if or .LastPageNum .NextPageNum}} | |||
| <ul class="pagination"> | |||
| {{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.LastPageNum}}">« {{.i18n.Tr "admin.prev"}}</a></li>{{end}} | |||
| {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{AppSubUrl}}/admin/users?p={{.NextPageNum}}">» {{.i18n.Tr "admin.next"}}</a></li>{{end}} | |||
| </ul> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||
| @@ -24,7 +24,28 @@ | |||
| </div> | |||
| <div id="feature-wrapper"> | |||
| <div class="container clear"> | |||
| {{if eq .Lang "zh-CN"}} | |||
| {{if eq .Lang "de-DE"}} | |||
| <div class="grid-1-2 left"> | |||
| <i class="octicon octicon-flame"></i> | |||
| <b>Einfach zu installieren</b> | |||
| <p>Starte einfach <a target="_blank" href="http://gogs.io/docs/installation/install_from_binary.html">die Anwendung</a> für deine Plattform. Gogs gibt es auch für <a target="_blank" href="https://github.com/gogits/gogs/tree/master/dockerfiles">Docker</a>, <a target="_blank" href="https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs">Vagrant</a> oder als <a target="_blank" href="http://gogs.io/docs/installation/install_from_packages.html">Installationspaket</a>.</p> | |||
| </div> | |||
| <div class="grid-1-2 left"> | |||
| <i class="octicon octicon-device-desktop"></i> | |||
| <b>Plattformübergreifend</b> | |||
| <p>Gogs läuft überall. <a target="_blank" href="http://golang.org/">Go</a> kompiliert für: Windows, Mac OS X, Linux, ARM, etc. Wähle dasjenige System, was dir am meisten gefällt!</p> | |||
| </div> | |||
| <div class="grid-1-2 left"> | |||
| <i class="octicon octicon-rocket"></i> | |||
| <b>Leichtgewicht</b> | |||
| <p>Gogs hat minimale Systemanforderungen und kann selbst auf einem günstigen und stromsparenden Raspberry Pi betrieben werden.</p> | |||
| </div> | |||
| <div class="grid-1-2 left"> | |||
| <i class="octicon octicon-code"></i> | |||
| <b>Quelloffen</b> | |||
| <p>Der komplette Code befindet sich auf <a target="_blank" href="https://github.com/gogits/gogs/">GitHub</a>! Unterstütze uns bei der Verbesserung dieses Projekts. Trau dich!</p> | |||
| </div> | |||
| {{else if eq .Lang "zh-CN"}} | |||
| <div class="grid-1-2 left"> | |||
| <i class="octicon octicon-flame"></i> | |||
| <b>易安装</b> | |||
| @@ -1,2 +1,3 @@ | |||
| {{if .Flash.ErrorMsg}}<span class="alert alert-red alert-radius block text-bold"><i class="octicon octicon-alert"></i>{{.Flash.ErrorMsg}}</span>{{end}} | |||
| {{if .Flash.SuccessMsg}}<div class="alert alert-green alert-radius block"><i class="octicon octicon-check"></i>{{.Flash.SuccessMsg}}</div>{{end}} | |||
| {{if .Flash.SuccessMsg}}<div class="alert alert-green alert-radius block"><i class="octicon octicon-check"></i>{{.Flash.SuccessMsg}}</div>{{end}} | |||
| {{if .Flash.InfoMsg}}<div class="alert alert-blue alert-radius block"><i class="octicon octicon-info"></i>{{.Flash.InfoMsg}}</div>{{end}} | |||
| @@ -27,7 +27,7 @@ | |||
| </div> | |||
| <div id="org-repo-list"> | |||
| {{range .Repos}} | |||
| {{if or $isMember (not .IsPrivate)}} | |||
| {{if .HasAccess $.SignedUser.Name}} | |||
| <div class="org-repo-item"> | |||
| <ul class="org-repo-status right"> | |||
| <li><i class="octicon octicon-star"></i> {{.NumStars}}</li> | |||
| @@ -1,10 +1,12 @@ | |||
| <div id="commits-list"> | |||
| <div class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| {{if not .IsDiffCompare}} | |||
| <form class="search pull-right" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form"> | |||
| <input class="ipt ipt-radius" type="search" name="q" placeholder="{{.i18n.Tr "repo.commits.search"}}" value="{{.Keyword}}" /> | |||
| <button class="btn btn-black btn-small btn-radius">{{.i18n.Tr "repo.commits.find"}}</button> | |||
| </form> | |||
| {{end}} | |||
| <h4>{{.CommitCount}} {{.i18n.Tr "repo.commits.commits"}}</h4> | |||
| </div> | |||
| <table class="panel-body table commit-list table-striped"> | |||
| @@ -31,7 +33,7 @@ | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| {{if not .IsSearchPage}} | |||
| {{if and (not .IsSearchPage) (not .IsDiffCompare)}} | |||
| <ul class="pagination"> | |||
| {{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« {{.i18n.Tr "repo.commits.newer"}}</a></li>{{end}} | |||
| {{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» {{.i18n.Tr "repo.commits.older"}}</a></li>{{end}} | |||
| @@ -1,49 +1,54 @@ | |||
| {{template "base/head" .}} | |||
| {{template "base/navbar" .}} | |||
| {{template "repo/nav" .}} | |||
| <div id="body" class="container" data-page="repo"> | |||
| <div id="source"> | |||
| {{if .IsDiffCompare }} | |||
| <div class="panel panel-info diff-box diff-head-box"> | |||
| <div class="panel-heading"> | |||
| <a class="pull-right btn btn-primary btn-sm" rel="nofollow" href="{{.SourcePath}}">Browse Source</a> | |||
| <h4><a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="label label-success">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="label label-success">{{ShortSha .AfterCommitId}}</a></h4> | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="repo-wrapper"> | |||
| {{template "repo/header" .}} | |||
| <div class="container clear" id="diff-page"> | |||
| {{if .IsDiffCompare }} | |||
| <div class="panel panel-info panel-radius compare-head-box"> | |||
| <div class="panel-header"> | |||
| <a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{.SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a> | |||
| <h4><a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="label label-green">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="label label-green">{{ShortSha .AfterCommitId}}</a></h4> | |||
| </div> | |||
| <div class="panel-body compare"> | |||
| {{template "repo/commits_table" .}} | |||
| {{template "repo/commits_table" .}} | |||
| </div> | |||
| </div> | |||
| {{else}} | |||
| <div class="panel panel-info diff-box diff-head-box"> | |||
| <div class="panel-heading"> | |||
| <a class="pull-right btn btn-primary btn-sm" rel="nofollow" href="{{.SourcePath}}">Browse Source</a> | |||
| {{else}} | |||
| <div class="panel panel-info panel-radius diff-head-box"> | |||
| <div class="panel-header"> | |||
| <a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{.SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a> | |||
| <h4>{{.Commit.Message}}</h4> | |||
| </div> | |||
| <div class="panel-body"> | |||
| <span class="pull-right"> | |||
| <ul class="list-unstyled"> | |||
| {{range .Parents}} | |||
| <li>parent <a href="{{$.RepoLink}}/commit/{{.}}"><span class="label label-default sha">{{ShortSha .}}</span></a></li> | |||
| {{end}} | |||
| <li>commit <span class="label label-default sha">{{ShortSha .CommitId}}</span></li> | |||
| </ul> | |||
| <ul class="list-unstyled"> | |||
| <li class="inline">{{.i18n.Tr "repo.diff.parent"}}</li> | |||
| {{range .Parents}} | |||
| <li class="inline"><a href="{{$.RepoLink}}/commit/{{.}}"><span class="label label-blue">{{ShortSha .}}</span></a></li> | |||
| {{end}} | |||
| <li class="inline">{{.i18n.Tr "repo.diff.commit"}} <span class="label label-blue">{{ShortSha .CommitId}}</span></li> | |||
| </ul> | |||
| </span> | |||
| <p class="author"> | |||
| <img class="avatar" src="{{AvatarLink .Commit.Author.Email}}" alt=""/> | |||
| <a class="name" href="{{AppSubUrl}}/user/email2user?email={{.Commit.Author.Email}}"><strong>{{.Commit.Author.Name}}</strong></a> | |||
| <span class="time">{{TimeSince .Commit.Author.When $.Lang}}</span> | |||
| <img class="avatar-30" src="{{AvatarLink .Commit.Author.Email}}" /> | |||
| {{if .Author}} | |||
| <a href="{{AppSubUrl}}/{{.Author}}"><strong>{{.Commit.Author.Name}}</strong></a> | |||
| {{else}} | |||
| <strong>{{.Commit.Author.Name}}</strong> | |||
| {{end}} | |||
| <span class="text-grey" id="authored-time">{{TimeSince .Commit.Author.When $.Lang}}</span> | |||
| </p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| {{if .DiffNotAvailable}} | |||
| <h4>Diff Data Not Available.</h4> | |||
| <h4>{{.i18n.Tr "repo.diff.data_not_available"}}</h4> | |||
| {{else}} | |||
| <div class="diff-detail-box diff-box"> | |||
| <a class="pull-right btn btn-default" data-toggle="collapse" data-target="#diff-files">Show Diff Stats</a> | |||
| <a class="pull-right btn btn-gray btn-header btn-radius text-black" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a> | |||
| <p class="showing"> | |||
| <i class="fa fa-retweet"></i> | |||
| <strong> {{.Diff.NumFiles}} changed files</strong> with <strong>{{.Diff.TotalAddition}} additions</strong> and <strong>{{.Diff.TotalDeletion}} deletions</strong>. | |||
| {{.i18n.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}} | |||
| </p> | |||
| <ol class="detail-files collapse" id="diff-files"> | |||
| {{range .Diff.Files}} | |||
| @@ -57,7 +62,7 @@ | |||
| </span> | |||
| <span class="del" data-line="{{.Deletion}}">{{.Deletion}}</span> | |||
| {{else}} | |||
| <span>BIN</span> | |||
| <span>{{$.i18n.Tr "repo.diff.bin"}}</span> | |||
| {{end}} | |||
| </div> | |||
| <!-- todo finish all file status, now modify, add, delete and rename --> | |||
| @@ -69,8 +74,8 @@ | |||
| </div> | |||
| {{range .Diff.Files}} | |||
| <div class="panel panel-default diff-file-box diff-box file-content" id="diff-{{.Index}}"> | |||
| <div class="panel-heading"> | |||
| <div class="panel panel-radius diff-file-box diff-box file-content" id="diff-{{.Index}}"> | |||
| <div class="panel-header"> | |||
| <div class="diff-counter count pull-left"> | |||
| {{if not .IsBin}} | |||
| <span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span> | |||
| @@ -80,10 +85,10 @@ | |||
| </span> | |||
| <span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span> | |||
| {{else}} | |||
| BIN | |||
| {{$.i18n.Tr "repo.diff.bin"}} | |||
| {{end}} | |||
| </div> | |||
| <a class="btn btn-default btn-sm pull-right" rel="nofollow" href="{{$.SourcePath}}/{{.Name}}">View File</a> | |||
| <a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{$.SourcePath}}/{{.Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a> | |||
| <span class="file">{{.Name}}</span> | |||
| </div> | |||
| {{$isImage := (call $.IsImageFile .Name)}} | |||
| @@ -117,8 +122,9 @@ | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| <br> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| {{template "ng/base/footer" .}} | |||
| @@ -54,16 +54,16 @@ | |||
| {{end}} | |||
| {{end}} | |||
| </li> | |||
| <!-- <li id="repo-commits-jump" class="repo-jump right"> | |||
| <li id="repo-commits-jump" class="repo-jump right"> | |||
| <a href="#"> | |||
| <button class="btn btn-small btn-gray btn-right-radius"><i class="octicon octicon-git-commit"></i></button> | |||
| </a> | |||
| </li> | |||
| <li id="repo-find-jump" class="repo-jump right"> | |||
| <a href="#"> | |||
| <button class="btn btn-small btn-gray btn-left-radius"><i class="octicon octicon-list-unordered"></i></button> | |||
| <button class="btn btn-small btn btn-small btn-gray btn-left-radius"><i class="octicon octicon-list-unordered"></i></button> | |||
| </a> | |||
| </li> --> | |||
| </li> | |||
| </ul> | |||
| {{if .IsFile}} | |||
| {{template "repo/view_file" .}} | |||
| @@ -71,7 +71,7 @@ | |||
| {{range .ClosedMilestones}} | |||
| <li class="milestone-item" data-id="{{.Id}}"> | |||
| <p><strong>{{.Name}}</strong></p> | |||
| <p>Closed {{TimeSince .ClosedDate}}</p> | |||
| <p>Closed {{TimeSince .ClosedDate $.Lang}}</p> | |||
| </li> | |||
| {{end}} | |||
| </ul> | |||
| @@ -236,7 +236,7 @@ | |||
| {{range .ClosedMilestones}} | |||
| <li class="milestone-item" data-id="{{.Id}}"> | |||
| <p><strong>{{.Name}}</strong></p> | |||
| <p>Closed {{TimeSince .ClosedDate}}</p> | |||
| <p>Closed {{TimeSince .ClosedDate $.Lang}}</p> | |||
| </li> | |||
| {{end}} | |||
| </ul> | |||
| @@ -0,0 +1,41 @@ | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="repo-wrapper"> | |||
| {{template "repo/header" .}} | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="repo-setting" class="container clear"> | |||
| {{template "repo/settings/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div id="repo-hooks-panel" class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "repo.settings.githooks"}}</strong> | |||
| </div> | |||
| <form class="form form-align panel-body" id="repo-setting-form" action="{{.RepoLink}}/settings/hooks/git/{{.Hook.Name}}" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <div class="text-center panel-desc">{{.i18n.Tr "repo.settings.githook_edit_desc"}}</div> | |||
| {{with .Hook}} | |||
| <div class="field"> | |||
| <label>{{$.i18n.Tr "repo.settings.githook_name"}}</label> | |||
| <label class="text-left">{{.Name}}</label> | |||
| </div> | |||
| <div class="field clear"> | |||
| <label class="left" for="content">{{$.i18n.Tr "repo.settings.githook_content"}}</label> | |||
| <textarea class="ipt-textarea ipt-large ipt-radius" id="content" name="content" cols="60" rows="20" wrap="off">{{if .IsActive}}{{.Content}}{{else}}{{.Sample}}{{end}}</textarea> | |||
| </div> | |||
| <div class="field"> | |||
| <span class="form-label"></span> | |||
| <button class="btn btn-green btn-large btn-radius" id="change-reponame-btn" href="#change-reponame-modal">{{$.i18n.Tr "repo.settings.update_githook"}}</button> | |||
| </div> | |||
| {{end}} | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||
| @@ -0,0 +1,37 @@ | |||
| {{template "ng/base/head" .}} | |||
| {{template "ng/base/header" .}} | |||
| <div id="repo-wrapper"> | |||
| {{template "repo/header" .}} | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="repo-setting" class="container clear"> | |||
| {{template "repo/settings/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div id="repo-hooks-panel" class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "repo.settings.githooks"}}</strong> | |||
| </div> | |||
| <ul class="panel-body setting-list"> | |||
| <li>{{.i18n.Tr "repo.settings.githooks_desc" | Str2html}}</li> | |||
| {{range .Hooks}} | |||
| <li> | |||
| {{if .IsActive}} | |||
| <span class="left text-success"><i class="octicon octicon-check"></i></span> | |||
| {{else}} | |||
| <span class="left text-grey"><i class="octicon octicon-primitive-dot"></i></span> | |||
| {{end}} | |||
| <span>{{.Name}}</span> | |||
| <a href="{{$.RepoLink}}/settings/hooks/git/{{.Name}}" class="text-blue right"><i class="fa fa-pencil"></i></a> | |||
| </li> | |||
| {{end}} | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||
| @@ -5,6 +5,7 @@ | |||
| <li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{.RepoLink}}/settings">{{.i18n.Tr "repo.settings.options"}}</a></li> | |||
| <li {{if .PageIsSettingsCollaboration}}class="current"{{end}}><a href="{{.RepoLink}}/settings/collaboration">{{.i18n.Tr "repo.settings.collaboration"}}</a></li> | |||
| <li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{.RepoLink}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li> | |||
| <li {{if .PageIsSettingsGitHooks}}class="current"{{end}}><a href="{{.RepoLink}}/settings/hooks/git">{{.i18n.Tr "repo.settings.githooks"}}</a></li> | |||
| <!-- <li {{if .PageIsSettingsKeys}}class="current"{{end}}><a href="{{.RepoLink}}/settings/keys">{{.i18n.Tr "repo.settings.deploy_keys"}}</a></li> --> | |||
| </ul> | |||
| </div> | |||
| @@ -1,40 +0,0 @@ | |||
| {{template "base/head" .}} | |||
| {{template "base/navbar" .}} | |||
| {{template "repo/nav" .}} | |||
| {{template "repo/toolbar" .}} | |||
| <div id="body" class="container"> | |||
| <div id="source"> | |||
| <div class="source-toolbar"> | |||
| {{ $n := len .Treenames}} | |||
| {{if not .IsFile}}<button class="btn btn-default pull-right hidden"><i class="fa fa-plus-square"></i>Add File</button>{{end}} | |||
| <div class="dropdown branch-switch"> | |||
| <a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>{{if .IsBranch}}{{.BranchName}}{{else}}{{ShortSha .CommitId}}{{end}} | |||
| <b class="caret"></b></a> | |||
| <ul class="dropdown-menu"> | |||
| {{range .Branches}} | |||
| <li><a {{if eq . $.BranchName}}class="current" {{end}}href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/src/{{.}}">{{.}}</a></li> | |||
| {{end}} | |||
| </ul> | |||
| </div> | |||
| {{ $l := Subtract $n 1}} | |||
| <ol class="breadcrumb"> | |||
| <li class="root dir"> | |||
| <a href="{{.BranchLink}}">{{.Repository.Name}}</a></li> | |||
| {{range $i, $v := .Treenames}} | |||
| <li class="dir"> | |||
| {{if eq $i $l}}{{$v}} | |||
| {{else}} | |||
| <a href="{{$.BranchLink}}/{{index $.Paths $i}}">{{$v}}</a> | |||
| {{end}} | |||
| </li> | |||
| {{end}} | |||
| </ol> | |||
| </div> | |||
| {{if .IsFile}} | |||
| {{template "repo/single_file" .}} | |||
| {{else}} | |||
| {{template "repo/single_list" .}} | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -1,40 +0,0 @@ | |||
| {{template "base/head" .}} | |||
| {{template "base/navbar" .}} | |||
| {{template "repo/nav" .}} | |||
| {{template "repo/toolbar" .}} | |||
| <div id="body" class="container"> | |||
| <div id="source"> | |||
| <div class="panel panel-default guide-box clone-group-btn"> | |||
| <div class="panel-heading guide-head"> | |||
| <h4>Quick Guide</h4> | |||
| </div> | |||
| <div class="panel-body guide-content text-center"> | |||
| <h3>Clone this repository</h3> | |||
| <div class="input-group col-md-8 col-md-offset-2 guide-buttons"> | |||
| <span class="input-group-btn"> | |||
| <button class="btn btn-default" data-link="{{.CloneLink.SSH}}" type="button">SSH</button> | |||
| <button class="btn btn-default" data-link="{{.CloneLink.HTTPS}}" type="button">HTTPS</button> | |||
| </span> | |||
| <input type="text" class="form-control clone-group-url" id="guide-clone-url" value="" readonly/> | |||
| <span class="input-group-btn" style="position: relative"> | |||
| <button class="btn btn-default" type="button" data-toggle="tooltip" title="copy to clipboard" data-placement="top" data-init="copy" data-copy-val="val" data-copy-from="#guide-clone-url"><i class="fa fa-copy"></i></button> | |||
| </span> | |||
| </div> | |||
| <p>We recommend every repository include a <strong>README</strong>, <strong>LICENSE</strong>, and <strong>.gitignore</strong>.</p> | |||
| <hr/> | |||
| <h3>Create a new repository on the command line</h3> | |||
| <pre class="text-left"><code>touch README.md | |||
| git init | |||
| git add README.md | |||
| git commit -m "first commit" | |||
| git remote add origin <span class="clone-url"></span> | |||
| git push -u origin master</code></pre> | |||
| <hr/> | |||
| <h3>Push an existing repository from the command line</h3> | |||
| <pre class="text-left"><code>git remote add origin <span class="clone-url"></span> | |||
| git push -u origin master</code></pre> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -1,51 +0,0 @@ | |||
| <div class="panel panel-default file-content"> | |||
| <div class="panel-heading file-head"> | |||
| {{if .ReadmeExist}} | |||
| <i class="icon fa fa-book"></i> | |||
| {{if .ReadmeInSingle}} | |||
| {{.FileName}} | |||
| {{else}} | |||
| {{.FileName}} <span class="file-size">{{FileSize .FileSize}}</span> | |||
| {{end}} | |||
| {{else}} | |||
| <i class="icon fa fa-file-text-o"></i> | |||
| {{.FileName}} <span class="file-size">{{FileSize .FileSize}}</span> | |||
| {{end}} | |||
| {{if not .ReadmeInSingle}} | |||
| <div class="btn-group pull-right"> | |||
| <a class="btn btn-default hidden" href="#">Edit</a> | |||
| <a class="btn btn-default" href="{{.FileLink}}" rel="nofollow">Raw</a> | |||
| <a class="btn btn-default hidden" href="#">Blame</a> | |||
| <a class="btn btn-default" href="{{.RepoLink}}/commits/{{.BranchName}}/{{.TreeName}}">History</a> | |||
| <a class="btn btn-danger hidden" href="#">Delete</a> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| {{if not .FileIsText}} | |||
| <div class="panel-body file-body file-code code-view"> | |||
| {{if .IsImageFile}} | |||
| <img src="{{.FileLink}}"> | |||
| {{else}} | |||
| <a href="{{.FileLink}}" rel="nofollow" class="btn btn-default">View Raw</a> | |||
| {{end}} | |||
| </div> | |||
| {{else}} | |||
| {{if .ReadmeExist}} | |||
| <div class="panel-body file-body markdown"> | |||
| {{.FileContent|str2html}} | |||
| </div> | |||
| {{else}} | |||
| <div class="panel-body file-body file-code code-view"> | |||
| <table> | |||
| <tbody> | |||
| <tr> | |||
| <td class="lines-num"></td> | |||
| <td class="lines-code markdown"><pre class="prettyprint linenums{{if .FileExt}} lang-{{.FileExt}}{{end}}">{{.FileContent}}</pre></td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| @@ -1,51 +0,0 @@ | |||
| <div class="panel panel-default info-box"> | |||
| <div class="panel-heading info-head"> | |||
| <a href="{{AppSubUrl}}/{{.Username}}/{{.Reponame}}/commit/{{.LastCommit.Id}}" rel="nofollow">{{.LastCommit.Summary}}</a> | |||
| </div> | |||
| <div class="panel-body info-content"> | |||
| <a href="{{AppSubUrl}}/user/{{.LastCommit.Author.Name}}">{{.LastCommit.Author.Name}}</a> <span class="text-muted">{{TimeSince .LastCommit.Author.When}}</span> | |||
| </div> | |||
| <table class="panel-footer table file-list"> | |||
| <thead class="hidden"> | |||
| <tr> | |||
| <th class="icon"></th> | |||
| <th class="name">Filename</th> | |||
| <th class="text">Message</th> | |||
| <th class="date">Date modified</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| {{if .HasParentPath}} | |||
| <tr class="has-parent"> | |||
| <td class="icon"><a href="{{.BranchLink}}{{.ParentPath}}"><i class="fa fa-reply"></i></a></td> | |||
| <td class="name"><a href="{{.BranchLink}}{{.ParentPath}}">..</a></td> | |||
| <td class="text"></td> | |||
| <td class="date"></td> | |||
| </tr> | |||
| {{end}} | |||
| {{range $item := .Files}} | |||
| {{$entry := index $item 0}} | |||
| {{$commit := index $item 1}} | |||
| <tr {{if $entry.IsDir}}class="is-dir"{{end}}> | |||
| <td class="icon"> | |||
| <i class="fa {{if $entry.IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i> | |||
| </td> | |||
| <td class="name"> | |||
| <span class="wrap"> | |||
| <a href="{{$.BranchLink}}/{{$.TreePath}}{{$entry.Name}}">{{$entry.Name}}</a> | |||
| </span> | |||
| </td> | |||
| <td class="text"> | |||
| <span class="wrap"><a rel="nofollow" href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{$commit.Id}}">{{$commit.Summary}}</a></span> | |||
| </td> | |||
| <td class="date"> | |||
| <span class="wrap">{{TimeSince $commit.Committer.When}}</span> | |||
| </td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| {{if .ReadmeExist}} | |||
| {{template "repo/single_file" .}} | |||
| {{end}} | |||
| @@ -2,15 +2,23 @@ | |||
| <p class="panel-header"> | |||
| {{if .ReadmeExist}} | |||
| <i class="icon fa fa-book fa-lg"></i> | |||
| {{if .ReadmeInHome}} | |||
| {{if .ReadmeInList}} | |||
| <strong class="file-name">{{.FileName}}</strong> | |||
| {{else}} | |||
| <strong>{{.FileName}}</strong><span class="file-size">{{FileSize .FileSize}}</span> | |||
| {{end}} | |||
| {{else}} | |||
| <i class="icon fa fa-file-text-o"></i> | |||
| <strong class="file-name">{{.FileName}}</strong><span class="file-size">{{FileSize .FileSize}}</span> | |||
| <i class="icon fa fa-file-text-o"></i> | |||
| <strong class="file-name">{{.FileName}}</strong><span class="file-size">{{FileSize .FileSize}}</span> | |||
| {{end}} | |||
| {{if not .ReadmeInList}} | |||
| <a class="right" href="{{.RepoLink}}/commits/{{.BranchName}}/{{.TreeName}}"> | |||
| <button class="btn btn-medium btn-gray btn-right-radius btn-comb">{{.i18n.Tr "repo.file_history"}}</button> | |||
| </a> | |||
| <a class="right" href="{{.FileLink}}"> | |||
| <button class="btn btn-medium btn-gray btn-left-radius btn-comb">{{.i18n.Tr "repo.file_raw"}}</button> | |||
| </a> | |||
| {{end}} | |||
| </p> | |||
| <div class="{{if .ReadmeExist}}panel-content markdown{{end}} code-view" id="repo-code-view"> | |||
| {{if .ReadmeExist}} | |||
| @@ -20,7 +28,7 @@ | |||
| {{if .IsImageFile}} | |||
| <img src="{{.FileLink}}"> | |||
| {{else}} | |||
| <a href="{{.FileLink}}" rel="nofollow" class="btn btn-gray btn-radius">View Raw</a> | |||
| <a href="{{.FileLink}}" rel="nofollow" class="btn btn-gray btn-radius">{{.i18n.Tr "repo.file_view_raw"}}</a> | |||
| {{end}} | |||
| </div> | |||
| {{else if .FileSize}} | |||
| @@ -10,7 +10,7 @@ | |||
| <strong>{{ShortSha .LastCommit.Id.String}}</strong></a> | |||
| <span class="text-truncate">{{.LastCommit.Summary}}</span> | |||
| </span> | |||
| <span class="age right">{{TimeSince .LastCommit.Author.When .i18n.Lang}}</span> | |||
| <span class="age right">{{TimeSince .LastCommit.Author.When $.Lang}}</span> | |||
| </th> | |||
| </tr> | |||
| </thead> | |||
| @@ -45,7 +45,7 @@ | |||
| <td class="msg"> | |||
| <a class="text-truncate" href="{{AppSubUrl}}/{{$.Username}}/{{$.Reponame}}/commit/{{$commit.Id}}" rel="nofollow">{{$commit.Summary}}</a> | |||
| </td> | |||
| <td class="age">{{TimeSince $commit.Committer.When $.i18n.Lang}}</td> | |||
| <td class="age">{{TimeSince $commit.Committer.When $.Lang}}</td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| @@ -15,6 +15,8 @@ | |||
| {{$.i18n.Tr "action.create_issue" AppSubUrl .GetRepoLink $index .GetRepoLink $index | Str2html}} | |||
| {{else if eq .GetOpType 8}} | |||
| {{$.i18n.Tr "action.transfer_repo" .GetContent AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} | |||
| {{else if eq .GetOpType 9}} | |||
| {{$.i18n.Tr "action.push_tag" AppSubUrl .GetRepoLink .GetBranch .GetBranch AppSubUrl .GetRepoLink .GetRepoLink | Str2html}} | |||
| {{else if eq .GetOpType 10}} | |||
| {{ $index := index .GetIssueInfos 0}} | |||
| {{$.i18n.Tr "action.comment_issue" AppSubUrl .GetRepoLink $index .GetRepoLink $index | Str2html}} | |||
| @@ -28,6 +30,7 @@ | |||
| {{range $push.Commits}} | |||
| <li><img class="avatar-16" src="{{AvatarLink .AuthorEmail}}?s=16"> <a href="{{AppSubUrl}}/{{$repoLink}}/commit/{{.Sha1}}">{{ShortSha .Sha1}}</a> <span class="text-truncate grid-4-5">{{.Message}}</span></li> | |||
| {{end}} | |||
| {{if $push.CompareUrl}}<li><a href="{{$push.CompareUrl}}">{{$.i18n.Tr "action.compare_2_commits"}} »</a></li>{{end}} | |||
| </ul> | |||
| </div> | |||
| {{else if eq .GetOpType 6}} | |||