aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--cmd/web.go4
-rw-r--r--conf/locale/locale_en-US.ini9
-rwxr-xr-xconf/locale/locale_es-ES.ini250
-rwxr-xr-xconf/locale/locale_fr-CA.ini16
-rwxr-xr-xconf/locale/locale_ru-RU.ini46
-rw-r--r--docker/blocks/docker_gogs/Dockerfile2
-rw-r--r--docker/blocks/docker_gogs_dev/Dockerfile2
-rw-r--r--docker/templates/init_gogs.sh.tpl2
-rw-r--r--gogs.go2
-rw-r--r--models/action.go22
-rw-r--r--models/issue.go2
-rw-r--r--models/login.go3
-rw-r--r--models/org.go2
-rw-r--r--models/repo.go1
-rw-r--r--models/user.go23
-rw-r--r--modules/auth/auth_form.go5
-rw-r--r--modules/auth/ldap/ldap.go48
-rw-r--r--modules/auth/repo_form.go3
-rw-r--r--modules/auth/user_form.go2
-rw-r--r--modules/base/template.go14
-rw-r--r--modules/base/tool.go67
-rw-r--r--modules/git/signature.go29
-rw-r--r--modules/mailer/mailer.go10
-rw-r--r--modules/middleware/context.go12
-rw-r--r--modules/middleware/repo.go3
-rw-r--r--public/ng/css/gogs.css4
-rw-r--r--public/ng/js/gogs.js37
-rw-r--r--public/ng/less/gogs/repository.less4
-rw-r--r--routers/admin/auths.go42
-rw-r--r--routers/api/v1/repo.go75
-rw-r--r--routers/org/setting.go15
-rw-r--r--routers/repo/issue.go19
-rw-r--r--routers/repo/repo.go28
-rw-r--r--routers/repo/setting.go5
-rw-r--r--routers/user/auth.go5
-rw-r--r--routers/user/setting.go91
-rwxr-xr-xscripts/less.sh5
-rw-r--r--templates/.VERSION2
-rw-r--r--templates/admin/auth/edit.tmpl16
-rw-r--r--templates/admin/auth/list.tmpl4
-rw-r--r--templates/admin/org/list.tmpl2
-rw-r--r--templates/admin/repo/list.tmpl2
-rw-r--r--templates/admin/user/list.tmpl2
-rw-r--r--templates/base/head.tmpl2
-rw-r--r--templates/ng/base/head.tmpl2
-rw-r--r--templates/org/base/header.tmpl2
-rw-r--r--templates/org/home.tmpl140
-rw-r--r--templates/org/settings/nav.tmpl20
-rw-r--r--templates/org/settings/options.tmpl114
-rw-r--r--templates/repo/bare.tmpl4
-rw-r--r--templates/repo/diff.tmpl10
-rw-r--r--templates/repo/migrate.tmpl4
-rw-r--r--templates/repo/settings/options.tmpl5
-rw-r--r--templates/user/profile.tmpl2
-rw-r--r--templates/user/settings/applications.tmpl2
-rw-r--r--templates/user/settings/email.tmpl6
-rw-r--r--templates/user/settings/social.tmpl2
-rw-r--r--templates/user/settings/sshkeys.tmpl2
59 files changed, 662 insertions, 594 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fc21ee03..411a8e93 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -52,7 +52,7 @@ We're trying very hard to keep Gogs lean and focused. We don't want it to do eve
### Ask For Help
-Before opening a new issue, please check to make sure your problem isn't already addressed on the [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md) and [FAQs](http://gogs.io/docs/intro/faqs.html) pages.
+Before opening an issue, please make sure your problem isn't already addressed on the [Troubleshooting](http://gogs.io/docs/intro/troubleshooting.md) and [FAQs](http://gogs.io/docs/intro/faqs.html) pages.
## Things To Notice
diff --git a/cmd/web.go b/cmd/web.go
index 4b06a882..1b692ceb 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -79,7 +79,7 @@ func checkVersion() {
// Check dependency version.
checkers := []VerChecker{
{"github.com/Unknwon/macaron", macaron.Version, "0.5.1"},
- {"github.com/macaron-contrib/binding", binding.Version, "0.0.4"},
+ {"github.com/macaron-contrib/binding", binding.Version, "0.0.5"},
{"github.com/macaron-contrib/cache", cache.Version, "0.0.7"},
{"github.com/macaron-contrib/csrf", csrf.Version, "0.0.3"},
{"github.com/macaron-contrib/i18n", i18n.Version, "0.0.5"},
@@ -229,7 +229,7 @@ func runWeb(ctx *cli.Context) {
})
m.Any("/*", func(ctx *middleware.Context) {
- ctx.JSON(404, &base.ApiJsonErr{"Not Found", base.DOC_URL})
+ ctx.HandleAPI(404, "Page not found")
})
})
})
diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini
index 6b59be73..f05287f5 100644
--- a/conf/locale/locale_en-US.ini
+++ b/conf/locale/locale_en-US.ini
@@ -281,13 +281,13 @@ init_readme = Initialize this repository with a README.md
create_repo = Create Repository
default_branch = Default Branch
mirror_interval = Mirror Interval (hour)
-goget_meta = Go-Get Meta
-goget_meta_helper = This repository will be <span class="label label-blue label-radius">Go-Getable</span>
need_auth = Need Authorization
migrate_type = Migration Type
migrate_type_helper = This repository will be a <span class="label label-blue label-radius">Mirror</span>
migrate_repo = Migrate Repository
+migrate.clone_address = Clone Address
+migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
copy_link = Copy
click_to_copy = Copy to clipboard
@@ -595,7 +595,10 @@ auths.domain = Domain
auths.host = Host
auths.port = Port
auths.base_dn = Base DN
-auths.attributes = Search Attributes
+auths.attribute_username = Username attribute
+auths.attribute_name = First name attribute
+auths.attribute_surname = Surname attribute
+auths.attribute_mail = E-mail attribute
auths.filter = Search Filter
auths.ms_ad_sa = Ms Ad SA
auths.smtp_auth = SMTP Authorization Type
diff --git a/conf/locale/locale_es-ES.ini b/conf/locale/locale_es-ES.ini
index 046bab89..fc235f15 100755
--- a/conf/locale/locale_es-ES.ini
+++ b/conf/locale/locale_es-ES.ini
@@ -516,8 +516,8 @@ dashboard.git_gc_repos=Ejecutar la recolección de basura en los repositorios
dashboard.git_gc_repos_success=Todos los repositorios han ejecutado correctamente el recolector de basuras.
dashboard.resync_all_sshkeys=Reescribir el fichero '.ssh/authorized_key'(atención: se perderán las claves que no pertenezcan a Gogs)
dashboard.resync_all_sshkeys_success=Todas las claves públicas se han reescrito correctamente.
-dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
-dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
+dashboard.resync_all_update_hooks=Reescribir todos los hooks de actualización de los repositorios (necesario cuando se modifica la ruta de configuración personalizada)
+dashboard.resync_all_update_hooks_success=Todos los hooks de actualización de los repositorios se han reescrito correctamente.
dashboard.server_uptime=Uptime del Servidor
dashboard.current_goroutine=Gorutinas Actuales
@@ -547,62 +547,62 @@ dashboard.last_gc_time=Tiempo desde el Último GC
dashboard.total_gc_time=Pausa Total por GC
dashboard.total_gc_pause=Pausa Total por GC
dashboard.last_gc_pause=Última Pausa por GC
-dashboard.gc_times=GC Times
-
-users.user_manage_panel=User Manage Panel
-users.new_account=Create New Account
-users.name=Name
-users.activated=Activated
-users.admin=Admin
-users.repos=Repos
-users.created=Created
-users.edit=Edit
-users.auth_source=Authorization Source
+dashboard.gc_times=Ejecuciones GC
+
+users.user_manage_panel=Panel de Gestión de Usuarios
+users.new_account=Crear Nueva Cuenta
+users.name=Nombre
+users.activated=Activado
+users.admin=Administrador
+users.repos=Repositorios
+users.created=Creado
+users.edit=Editar
+users.auth_source=Origen de Autorización
users.local=Local
-users.auth_login_name=Authorization Login Name
-users.update_profile_success=Account profile has been updated successfully.
+users.auth_login_name=Nombre de Usuario de Autorización
+users.update_profile_success=El perfil de la cuenta se ha actualizado correctamente.
users.edit_account=Editar Cuenta
users.is_activated=Esta cuenta está activada
-users.is_admin=This account has administrator permissions
-users.allow_git_hook=This account has permissions to create Git hooks
-users.update_profile=Update Account Profile
-users.delete_account=Delete This Account
-users.still_own_repo=This account still have ownership of repository, you have to delete or transfer them first.
-users.still_has_org=This account still have membership of organization, you have to left or delete them first.
-
-orgs.org_manage_panel=Organization Manage Panel
-orgs.name=Name
-orgs.teams=Teams
-orgs.members=Members
-
-repos.repo_manage_panel=Repository Manage Panel
-repos.owner=Owner
-repos.name=Name
-repos.private=Private
-repos.watches=Watches
-repos.stars=Stars
-repos.issues=Issues
-
-auths.auth_manage_panel=Authorization Manage Panel
-auths.new=Add New Authorization Source
-auths.name=Name
-auths.type=Type
-auths.enabled=Enabled
-auths.updated=Updated
-auths.auth_type=Authorization Type
-auths.auth_name=Authorization Name
-auths.domain=Domain
+users.is_admin=Esta cuenta tiene permisos de administrador
+users.allow_git_hook=Esta cuenta tiene permisos para crear hooks de Git
+users.update_profile=Actualizar Perfil de la Cuenta
+users.delete_account=Eliminar esta Cuenta
+users.still_own_repo=Esta cuenta es propietaria de uno o más repositorios, tienes que borrarlos o transferirlos primero.
+users.still_has_org=Esta cuenta es miembro de una o más organizaciones, tienes que abandonarlas o eliminarlas primero.
+
+orgs.org_manage_panel=Panel de Gestión de Organización
+orgs.name=Nombre
+orgs.teams=Equipos
+orgs.members=Miembros
+
+repos.repo_manage_panel=Panel de Gestión de Repositorios
+repos.owner=Propietario
+repos.name=Nombre
+repos.private=Privado
+repos.watches=Vigilantes
+repos.stars=Estrellas
+repos.issues=Incidencias
+
+auths.auth_manage_panel=Panel de Gestión de Autorizaciones
+auths.new=Añadir nuevo origen de autorización
+auths.name=Nombre
+auths.type=Tipo
+auths.enabled=Activo
+auths.updated=Actualizado
+auths.auth_type=Tipo de Autorización
+auths.auth_name=Nombre de Autorización
+auths.domain=Dominio
auths.host=Host
-auths.port=Port
+auths.port=Puerto
auths.base_dn=Base DN
-auths.attributes=Search Attributes
-auths.filter=Search Filter
+auths.attributes=Atributos de búsqueda
+auths.filter=Filtro de Búsqueda
auths.ms_ad_sa=Ms Ad SA
-auths.smtp_auth=SMTP Authorization Type
+auths.smtp_auth=Tipo de Autorización SMTP
auths.smtphost=SMTP Host
-auths.smtpport=SMTP Port
-auths.enable_tls=Enable TLS Encryption
-auths.enable_auto_register=Enable Auto Registration
+auths.smtpport=Puerto SMTP
+auths.enable_tls=Habilitar Cifrado TLS
+auths.enable_auto_register=Hablilitar Auto-Registro
auths.tips=Consejos
auths.edit=Editar la Configuración de Autorización
auths.activated=Esta autenticación ha sido activada
@@ -625,7 +625,7 @@ config.repo_root_path=Ruta del Repositorio
config.static_file_root_path=Ruta de los Ficheros Estáticos
config.log_file_root_path=Ruta de los Ficheros de Log
config.script_type=Tipo de Script
-config.reverse_auth_user=Reverse Authentication User
+config.reverse_auth_user=Autenticación Inversa de Usuario
config.db_config=Configuración de la Base de Datos
config.db_type=Tipo
config.db_host=Host
@@ -642,83 +642,83 @@ config.show_registration_button=Mostrar Botón de Registro
config.require_sign_in_view=Solicitar la Vista de Inicio de Sesión
config.mail_notify=Notificación por Correo Electrónico
config.enable_cache_avatar=Activar la Caché de Avatar
-config.active_code_lives=Active Code Lives
-config.reset_password_code_lives=Reset Password Code Lives
-config.webhook_config=Webhook Configuration
-config.task_interval=Task Interval
-config.deliver_timeout=Deliver Timeout
-config.skip_tls_verify=Skip TLS Verify
-config.mailer_config=Mailer Configuration
-config.mailer_enabled=Enabled
-config.mailer_name=Name
+config.active_code_lives=Habilitar Vida del Código
+config.reset_password_code_lives=Restablecer Contraseña de Vida del Código
+config.webhook_config=Configuración de Webhooks
+config.task_interval=Intervalo de Tareas
+config.deliver_timeout=Timeout de Entrega
+config.skip_tls_verify=Omitir la Verificación TLS
+config.mailer_config=Configuración del Mailer
+config.mailer_enabled=Activado
+config.mailer_name=Nombre
config.mailer_host=Host
-config.mailer_user=User
-config.oauth_config=OAuth Configuration
-config.oauth_enabled=Enabled
-config.cache_config=Cache Configuration
-config.cache_adapter=Cache Adapter
-config.cache_interval=Cache Interval
-config.cache_conn=Cache Connection
-config.session_config=Session Configuration
-config.session_provider=Session Provider
-config.provider_config=Provider Config
-config.cookie_name=Cookie Name
-config.enable_set_cookie=Enable Set Cookie
-config.gc_interval_time=GC Interval Time
-config.session_life_time=Session Life Time
-config.https_only=HTTPS Only
-config.cookie_life_time=Cookie Life Time
-config.picture_config=Picture Configuration
-config.picture_service=Picture Service
-config.disable_gravatar=Disable Gravatar
-config.log_config=Log Configuration
-config.log_mode=Log Mode
-
-monitor.cron=Cron Tasks
-monitor.name=Name
-monitor.schedule=Schedule
-monitor.next=Next Time
-monitor.previous=Previous Time
-monitor.execute_times=Execute Times
-monitor.process=Running Processes
-monitor.desc=Description
-monitor.start=Start Time
-monitor.execute_time=Execution Time
-
-notices.system_notice_list=System Notices
-notices.type=Type
-notices.type_1=Repository
-notices.desc=Description
+config.mailer_user=Usuario
+config.oauth_config=Configuración OAuth
+config.oauth_enabled=Activado
+config.cache_config=Configuración de la Caché
+config.cache_adapter=Adaptador de la Caché
+config.cache_interval=Intervalo de la Caché
+config.cache_conn=Conexión de la Caché
+config.session_config=Configuración de la Sesión
+config.session_provider=Proveedor de la Sesión
+config.provider_config=Configuración del Proveedor
+config.cookie_name=Nombre de la Cookie
+config.enable_set_cookie=Activar Establecimiento de Cookie
+config.gc_interval_time=Intervalo de tiempo del GC
+config.session_life_time=Tiempo de Vida de la Sesión
+config.https_only=Sólo HTTPS
+config.cookie_life_time=Tiempo de Vida de la Cookie
+config.picture_config=Configuración de Imagen
+config.picture_service=Servicio de Imágen
+config.disable_gravatar=Desactivar Gravatar
+config.log_config=Configuración del Log
+config.log_mode=Modo del Log
+
+monitor.cron=Tareas de Cron
+monitor.name=Nombre
+monitor.schedule=Agenda
+monitor.next=Próxima Vez
+monitor.previous=Vez Anterior
+monitor.execute_times=Ejecuciones
+monitor.process=Procesos en Ejecución
+monitor.desc=Descripción
+monitor.start=Hora de Inicio
+monitor.execute_time=Tiempo de ejecución
+
+notices.system_notice_list=Notificaciones del Sistema
+notices.type=Tipo
+notices.type_1=Repositorio
+notices.desc=Descripción
notices.op=Op.
-notices.delete_success=System notice has been deleted successfully.
+notices.delete_success=La notificación del sistema se ha eliminado correctamente.
[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/issues/%s">%[1]s#%[2]s</a>`
-comment_issue=`commented on issue <a href="%s/issues/%s">%[1]s#%[2]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
+create_repo=Repositorio creado <a href="%s/%s">%s</a>
+commit_repo=hizo push a <a href="%s/%s/src/%s">%s</a> en <a href="%s/%s">%s</a>
+create_issue=`incidencia abierta <a href="%s/issues/%s">%[1]s#%[2]s</a>`
+comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%[1]s#%[2]s</a>`
+transfer_repo=transfirió el repositorio <code>%s</code> a <a href="/%s%s">%s</a>
+push_tag=hizo push del tag <a href="%s/%s/src/%s">%s</a> a <a href="%s/%s">%s</a>
+compare_2_commits=Ver la comparación de estos 2 commits
[tool]
-ago=ago
-from_now=from now
-now=now
-1s=1 second %s
-1m=1 minute %s
-1h=1 hour %s
-1d=1 day %s
-1w=1 week %s
-1mon=1 month %s
-1y=1 year %s
-seconds=%d seconds %s
-minutes=%d minutes %s
-hours=%d hours %s
-days=%d days %s
-weeks=%d weeks %s
-months=%d months %s
-years=%d years %s
-raw_seconds=seconds
-raw_minutes=minutes
+ago=hace
+from_now=desde ahora
+now=ahora
+1s=1 segundo %s
+1m=1 minuto %s
+1h=1 hora %s
+1d=1 día %s
+1w=1 semana %s
+1mon=1 mes %s
+1y=1 año %s
+seconds=%d segundos %s
+minutes=%d minutos %s
+hours=%d horas %s
+days=%d días %s
+weeks=%d semanas %s
+months=%d meses %s
+years=%d años %s
+raw_seconds=segundos
+raw_minutes=minutos
diff --git a/conf/locale/locale_fr-CA.ini b/conf/locale/locale_fr-CA.ini
index 0aeae342..e744b9d9 100755
--- a/conf/locale/locale_fr-CA.ini
+++ b/conf/locale/locale_fr-CA.ini
@@ -59,8 +59,8 @@ run_user=Entrer un Utilisateur
run_user_helper=L'utilisateur doit avoir accès à la Racine du Référentiel et éxécuter Gogs.
domain=Domaine
domain_helper=Cela affecte les doublons d'URL SSH.
-http_port=HTTP Port
-http_port_helper=Port number which application will listen on.
+http_port=Port HTTP
+http_port_helper=Numéro de port que l'application écoutera.
app_url=URL de l'Application
app_url_helper=Cela affecte les doublons d'URL HTTP/HTTPS et le contenu d'e-mail.
email_title=Paramètres du Service de Messagerie (Facultatif)
@@ -514,10 +514,10 @@ dashboard.delete_repo_archives=Supprimer toutes les archives de référentiels
dashboard.delete_repo_archives_success=Toutes les archives de référentiels ont été supprimés avec succès.
dashboard.git_gc_repos=Collecter les déchets des référentiels
dashboard.git_gc_repos_success=Tous les référentiels ont effectué la collecte avec succès.
-dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
-dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
-dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
-dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
+dashboard.resync_all_sshkeys=Ré-écrire le fichier '.ssh/autorized_key' (attention : les clés hors-Gogs vont être perdues)
+dashboard.resync_all_sshkeys_success=Toutes les clés publiques ont été ré-écrites avec succès.
+dashboard.resync_all_update_hooks=Ré-écrire tous les hooks de mises à jour des dépôts (requis quand le chemin de la configuration personnalisé est modifié)
+dashboard.resync_all_update_hooks_success=Tous les hooks de mises à jour des dépôts ont été ré-écris avec succès.
dashboard.server_uptime=Durée de Marche Serveur
dashboard.current_goroutine=Goroutines actuelles
@@ -638,7 +638,7 @@ config.db_path_helper=("sqlite3" uniquement)
config.service_config=Configuration du Service
config.register_email_confirm=Nécessite une confirmation par courriel
config.disable_register=Désactiver l'Enregistrement
-config.show_registration_button=Show Register Button
+config.show_registration_button=Afficher le bouton d'enregistrement
config.require_sign_in_view=Connexion Obligatoire pour Visualiser
config.mail_notify=Mailer les Notifications
config.enable_cache_avatar=Activer le Cache d'Avatar
@@ -647,7 +647,7 @@ config.reset_password_code_lives=Réinitialiser le Mot De Passe des Limites de C
config.webhook_config=Configuration Webhook
config.task_interval=Intervalles de Tâches
config.deliver_timeout=Expiration d'Envoi
-config.skip_tls_verify=Skip TLS Verify
+config.skip_tls_verify=Ne pas vérifier TLS
config.mailer_config=Configuration du Maileur
config.mailer_enabled=Activé
config.mailer_name=Nom
diff --git a/conf/locale/locale_ru-RU.ini b/conf/locale/locale_ru-RU.ini
index e21dca14..731ba469 100755
--- a/conf/locale/locale_ru-RU.ini
+++ b/conf/locale/locale_ru-RU.ini
@@ -313,9 +313,9 @@ tags=Метки
issues=Обсуждения
commits=Коммиты
releases=Релизы
-file_raw=Raw
+file_raw=Исходник
file_history=История
-file_view_raw=View Raw
+file_view_raw=Посмотреть исходник
commits.commits=Коммиты
commits.search=Поиск коммитов
@@ -339,7 +339,7 @@ settings.update_settings=Обновить настройки
settings.change_reponame=Имя репозитория изменено
settings.change_reponame_desc=Имя хранилища изменено, вы хотите продолжить? Это действие повлияет на все ссылки, относящиеся к этому репозиторию.
settings.transfer=Передать права собственности
-settings.transfer_desc=Transfer this repo to another user or to an organization where you have admin rights.
+settings.transfer_desc=Передать репозиторий другому пользователю или организации где у вас есть права администратора.
settings.new_owner_has_same_repo=У нового владельца уже есть хранилище с таким названием.
settings.delete=Удалить этот репозиторий
settings.delete_desc=Как только вы удалите репозиторий — пути назад не будет. Удостоверьтесь, что вам это точно нужно.
@@ -352,7 +352,7 @@ settings.confirm_delete=Подтвердить удаление
settings.add_collaborator=Добавить нового соавтора
settings.add_collaborator_success=Был добавлен новый соавтор.
settings.remove_collaborator_success=Соавтор был удален.
-settings.user_is_org_member=User is organization member who cannot be added as a collaborator.
+settings.user_is_org_member=Пользователь является членом организации, члены которой не могут быть добавлены в качестве соавтора.
settings.add_webhook=Добавить 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="%s">Webhooks Guide</a>.
settings.githooks_desc=Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to apply custom operations.
@@ -399,12 +399,12 @@ release.ahead=<strong>%d</strong> commits to %s since this release
release.source_code=Исходный код
release.tag_name=Имя тега
release.target=Цель
-release.tag_helper=Choose an existing tag, or create a new tag on publish.
+release.tag_helper=Выберите существующий тег, или создайте новый.
release.release_title=Название релиза
release.content_with_md=Содержимое с <a href="%s">Markdown</a>
release.write=Запись
release.preview=Предварительный просмотр
-release.content_placeholder=Write some content
+release.content_placeholder=Напишите что-нибудь
release.loading=Загрузка...
release.prerelease_desc=Это предварительный релиз
release.prerelease_helper=We’ll point out that this release is identified as non-production ready.
@@ -443,10 +443,10 @@ settings.change_orgname_desc=Organization name has been changed, do you want to
settings.update_setting_success=Organization setting has been updated successfully.
settings.delete=Удалить Организацию
settings.delete_account=Удалить Эту Организацию
-settings.delete_prompt=The operation will delete this organization permanently, and <strong>CANNOT</strong> be undone!
+settings.delete_prompt=Это действие безвозвратно удалит эту организацию навсегда.
settings.confirm_delete_account=Подтвердить удаление
settings.delete_org_title=Удаление Организации
-settings.delete_org_desc=This organization is going to be deleted permanently, do you want to continue?
+settings.delete_org_desc=Эта организация будет удалена навсегда. Хотите всё-равно продолжить?
settings.hooks_desc=Добавьте автоматическое обновление, который будет вызываться для <strong>всех репозиций</strong> под этой Группой.
members.public=Публичный
@@ -455,7 +455,7 @@ members.private=Приватный
members.private_helper=Сделать Публичным
members.owner=Владелец
members.member=Участник
-members.conceal=Conceal
+members.conceal=Скрыть
members.remove=Удалить
members.leave=Покинуть
members.invite_desc=Начните вводить имя пользователя чтобы пригласить нового члена %s:
@@ -494,7 +494,7 @@ organizations=Организации
repositories=Репозитории
authentication=Авторизация
config=Настройки
-notices=System Notices
+notices=Системные уведомления
monitor=Мониторинг
prev=Предыдущий.
next=Следующий
@@ -506,15 +506,15 @@ dashboard.statistic_info=В базе данных Gogs записано <b>%d</b
dashboard.operation_name=Operation Name
dashboard.operation_switch=Переключить
dashboard.operation_run=Запуск
-dashboard.clean_unbind_oauth=Clean unbound OAuthes
-dashboard.clean_unbind_oauth_success=All unbind OAuthes have been deleted successfully.
+dashboard.clean_unbind_oauth=Удалить не привязанные OAUth
+dashboard.clean_unbind_oauth_success=Не привязанные OAuth аккаунты успешно удалены.
dashboard.delete_inactivate_accounts=Удалить все неактивированные учетные записи
dashboard.delete_inactivate_accounts_success=Все неактивированные учетные записи удалены успешно.
dashboard.delete_repo_archives=Удаление всех архивов репозиториев
dashboard.delete_repo_archives_success=Все архивы репозиториев были успешно удалены.
dashboard.git_gc_repos=Выполнить сборку мусора на репозиториях
dashboard.git_gc_repos_success=Сборка мусора на всех репозиториях успешно выполнена.
-dashboard.resync_all_sshkeys=Rewrite '.ssh/autorized_key' file (caution: non-Gogs keys will be lost)
+dashboard.resync_all_sshkeys=Переписать файл «.ssh/autorized_key» (осторожно: не Gogs ключи будут утеряны)
dashboard.resync_all_sshkeys_success=All public keys have been rewritten successfully.
dashboard.resync_all_update_hooks=Rewrite all update hook of repositories (needed when custom config path is changed)
dashboard.resync_all_update_hooks_success=All repositories' update hook have been rewritten successfully.
@@ -690,7 +690,7 @@ notices.type=Тип
notices.type_1=Репозиторий
notices.desc=Описание
notices.op=Op.
-notices.delete_success=System notice has been deleted successfully.
+notices.delete_success=Системное уведомление успешно удалено.
[action]
create_repo=создан репозиторий <a href="%s/%s"> %s</a>
@@ -699,26 +699,26 @@ create_issue=`opened issue <a href="%s/issues/%s">%[1]s#%[2]s</a>`
comment_issue=`commented on issue <a href="%s/issues/%s">%[1]s#%[2]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
+compare_2_commits=Просмотреть сравнение двух коммитов
[tool]
ago=ago
from_now=from now
now=сейчас
1s=1 second %s
-1m=1 minute %s
-1h=1 hour %s
-1d=1 day %s
-1w=1 week %s
+1m=1 минута %s
+1h=1 час %s
+1d=1 день %s
+1w=1 неделя %s
1mon=1 month %s
-1y=1 year %s
+1y=1 год %s
seconds=%d секунд %s
minutes=%d минут %s
hours=%d часов %s
-days=%d days %s
+days=%d дней %s
weeks=%d weeks %s
months=%d months %s
years=%d years %s
-raw_seconds=seconds
-raw_minutes=minutes
+raw_seconds=секунд
+raw_minutes=минут
diff --git a/docker/blocks/docker_gogs/Dockerfile b/docker/blocks/docker_gogs/Dockerfile
index 2c98cc50..efedc31a 100644
--- a/docker/blocks/docker_gogs/Dockerfile
+++ b/docker/blocks/docker_gogs/Dockerfile
@@ -4,7 +4,7 @@ FROM ubuntu:14.04
RUN apt-get update && apt-get install -y \
build-essential ca-certificates curl \
- bzr git mercurial \
+ bzr git mercurial openssh-client\
--no-install-recommends
ENV GOLANG_VERSION 1.3
diff --git a/docker/blocks/docker_gogs_dev/Dockerfile b/docker/blocks/docker_gogs_dev/Dockerfile
index 2a628c2d..ce653fbe 100644
--- a/docker/blocks/docker_gogs_dev/Dockerfile
+++ b/docker/blocks/docker_gogs_dev/Dockerfile
@@ -5,7 +5,7 @@ FROM ubuntu:14.04
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -qy \
build-essential ca-certificates curl \
- bzr git mercurial \
+ bzr git mercurial openssh-client\
--no-install-recommends
ENV GOLANG_VERSION 1.3
diff --git a/docker/templates/init_gogs.sh.tpl b/docker/templates/init_gogs.sh.tpl
index 26cff4e5..ada11f95 100644
--- a/docker/templates/init_gogs.sh.tpl
+++ b/docker/templates/init_gogs.sh.tpl
@@ -1,6 +1,6 @@
#!/bin/sh
-if [ ! -d "$DIRECTORY" ]; then
+if [ ! -d "$GOGS_CUSTOM_CONF_PATH" ]; then
mkdir -p $GOGS_CUSTOM_CONF_PATH
echo "
diff --git a/gogs.go b/gogs.go
index 34790b72..b2366b63 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
-const APP_VER = "0.5.13.0214 Beta"
+const APP_VER = "0.5.14.0222 Beta"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/models/action.go b/models/action.go
index 5cba2f51..a1a33f83 100644
--- a/models/action.go
+++ b/models/action.go
@@ -182,6 +182,17 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
issue.IsClosed = true
+ if err = issue.GetLabels(); err != nil {
+ return err
+ }
+ for _, label := range issue.Labels {
+ label.NumClosedIssues++
+
+ if err = UpdateLabel(label); err != nil {
+ return err
+ }
+ }
+
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
@@ -230,6 +241,17 @@ func updateIssuesCommit(userId, repoId int64, repoUserName, repoName string, com
}
issue.IsClosed = false
+ if err = issue.GetLabels(); err != nil {
+ return err
+ }
+ for _, label := range issue.Labels {
+ label.NumClosedIssues--
+
+ if err = UpdateLabel(label); err != nil {
+ return err
+ }
+ }
+
if err = UpdateIssue(issue); err != nil {
return err
} else if err = UpdateIssueUserPairsByStatus(issue.Id, issue.IsClosed); err != nil {
diff --git a/models/issue.go b/models/issue.go
index d9a24063..226ca3ca 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -561,7 +561,7 @@ func GetLabels(repoId int64) ([]*Label, error) {
// UpdateLabel updates label information.
func UpdateLabel(l *Label) error {
- _, err := x.Id(l.Id).Update(l)
+ _, err := x.Id(l.Id).AllCols().Update(l)
return err
}
diff --git a/models/login.go b/models/login.go
index 125e110a..1dc1b6ca 100644
--- a/models/login.go
+++ b/models/login.go
@@ -231,7 +231,7 @@ func UserSignIn(uname, passwd string) (*User, error) {
// Return the same LoginUserPlain semantic
// FIXME: https://github.com/gogits/gogs/issues/672
func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAPConfig, autoRegister bool) (*User, error) {
- mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
+ name, fn, sn, mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
if !logged {
// User not in LDAP, do nothing
return nil, ErrUserNotExist
@@ -247,6 +247,7 @@ func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAP
u = &User{
Name: name,
+ FullName: fn + " " + sn,
LoginType: LDAP,
LoginSource: sourceId,
LoginName: name,
diff --git a/models/org.go b/models/org.go
index 3d37a37d..b2f9c903 100644
--- a/models/org.go
+++ b/models/org.go
@@ -93,7 +93,7 @@ func CreateOrganization(org, owner *User) (*User, error) {
return nil, ErrUserNameIllegal
}
- isExist, err := IsUserExist(org.Name)
+ isExist, err := IsUserExist(0, org.Name)
if err != nil {
return nil, err
} else if isExist {
diff --git a/models/repo.go b/models/repo.go
index cdb838a1..179120a3 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -154,7 +154,6 @@ type Repository struct {
IsPrivate bool
IsBare bool
- IsGoget bool
IsMirror bool
*Mirror `xorm:"-"`
diff --git a/models/user.go b/models/user.go
index 2da0881c..a974e081 100644
--- a/models/user.go
+++ b/models/user.go
@@ -249,11 +249,13 @@ func (u *User) GetFullNameFallback() string {
// IsUserExist checks if given user name exist,
// the user name should be noncased unique.
-func IsUserExist(name string) (bool, error) {
+// If uid is presented, then check will rule out that one,
+// it is used when update a user name in settings page.
+func IsUserExist(uid int64, name string) (bool, error) {
if len(name) == 0 {
return false, nil
}
- return x.Get(&User{LowerName: strings.ToLower(name)})
+ return x.Where("id!=?", uid).Get(&User{LowerName: strings.ToLower(name)})
}
// IsEmailUsed returns true if the e-mail has been used.
@@ -278,7 +280,7 @@ func CreateUser(u *User) error {
return ErrUserNameIllegal
}
- isExist, err := IsUserExist(u.Name)
+ isExist, err := IsUserExist(0, u.Name)
if err != nil {
return err
} else if isExist {
@@ -397,6 +399,10 @@ func ChangeUserName(u *User, newUserName string) (err error) {
}
newUserName = strings.ToLower(newUserName)
+ if u.LowerName == newUserName {
+ // User only change letter cases.
+ return nil
+ }
// Update accesses of user.
accesses := make([]Access, 0, 10)
@@ -453,7 +459,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
// UpdateUser updates user's information.
func UpdateUser(u *User) error {
- has, err := x.Where("id!=?", u.Id).And("type=?", INDIVIDUAL).And("email=?", u.Email).Get(new(User))
+ has, err := x.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
if err != nil {
return err
} else if has {
@@ -627,7 +633,7 @@ func GetUserIdsByNames(names []string) []int64 {
return ids
}
-// Get all email addresses
+// GetEmailAddresses returns all e-mail addresses belongs to given user.
func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
emails := make([]*EmailAddress, 0, 5)
err := x.Where("uid=?", uid).Find(&emails)
@@ -641,7 +647,6 @@ func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
}
isPrimaryFound := false
-
for _, email := range emails {
if email.Email == u.Email {
isPrimaryFound = true
@@ -654,7 +659,11 @@ func GetEmailAddresses(uid int64) ([]*EmailAddress, error) {
// We alway want the primary email address displayed, even if it's not in
// the emailaddress table (yet)
if !isPrimaryFound {
- emails = append(emails, &EmailAddress{Email: u.Email, IsActivated: true, IsPrimary: true})
+ emails = append(emails, &EmailAddress{
+ Email: u.Email,
+ IsActivated: true,
+ IsPrimary: true,
+ })
}
return emails, nil
}
diff --git a/modules/auth/auth_form.go b/modules/auth/auth_form.go
index e9789634..c7b93896 100644
--- a/modules/auth/auth_form.go
+++ b/modules/auth/auth_form.go
@@ -18,7 +18,10 @@ type AuthenticationForm struct {
Port int `form:"port"`
UseSSL bool `form:"usessl"`
BaseDN string `form:"base_dn"`
- Attributes string `form:"attributes"`
+ AttributeUsername string `form:"attribute_username"`
+ AttributeName string `form:"attribute_name"`
+ AttributeSurname string `form:"attribute_surname"`
+ AttributeMail string `form:"attribute_mail"`
Filter string `form:"filter"`
MsAdSA string `form:"ms_ad_sa"`
IsActived bool `form:"is_actived"`
diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go
index 44c130a1..c78e241d 100644
--- a/modules/auth/ldap/ldap.go
+++ b/modules/auth/ldap/ldap.go
@@ -15,15 +15,18 @@ import (
// Basic LDAP authentication service
type Ldapsource struct {
- Name string // canonical name (ie. corporate.ad)
- Host string // LDAP host
- Port int // port number
- UseSSL bool // Use SSL
- BaseDN string // Base DN
- Attributes string // Attribute to search
- Filter string // Query filter to validate entry
- MsAdSAFormat string // in the case of MS AD Simple Authen, the format to use (see: http://msdn.microsoft.com/en-us/library/cc223499.aspx)
- Enabled bool // if this source is disabled
+ Name string // canonical name (ie. corporate.ad)
+ Host string // LDAP host
+ Port int // port number
+ UseSSL bool // Use SSL
+ BaseDN string // Base DN
+ AttributeUsername string // Username attribute
+ AttributeName string // First name attribute
+ AttributeSurname string // Surname attribute
+ AttributeMail string // E-mail attribute
+ Filter string // Query filter to validate entry
+ MsAdSAFormat string // in the case of MS AD Simple Authen, the format to use (see: http://msdn.microsoft.com/en-us/library/cc223499.aspx)
+ Enabled bool // if this source is disabled
}
//Global LDAP directory pool
@@ -32,18 +35,18 @@ var (
)
// Add a new source (LDAP directory) to the global pool
-func AddSource(name string, host string, port int, usessl bool, basedn string, attributes string, filter string, msadsaformat string) {
- ldaphost := Ldapsource{name, host, port, usessl, basedn, attributes, filter, msadsaformat, true}
+func AddSource(name string, host string, port int, usessl bool, basedn string, attribcn string, attribname string, attribsn string, attribmail string, filter string, msadsaformat string) {
+ ldaphost := Ldapsource{name, host, port, usessl, basedn, attribcn, attribname, attribsn, attribmail, filter, msadsaformat, true}
Authensource = append(Authensource, ldaphost)
}
//LoginUser : try to login an user to LDAP sources, return requested (attribute,true) if ok, ("",false) other wise
//First match wins
//Returns first attribute if exists
-func LoginUser(name, passwd string) (a string, r bool) {
+func LoginUser(name, passwd string) (cn, fn, sn, mail string, r bool) {
r = false
for _, ls := range Authensource {
- a, r = ls.SearchEntry(name, passwd)
+ cn, fn, sn, mail, r = ls.SearchEntry(name, passwd)
if r {
return
}
@@ -52,12 +55,12 @@ func LoginUser(name, passwd string) (a string, r bool) {
}
// searchEntry : search an LDAP source if an entry (name, passwd) is valide and in the specific filter
-func (ls Ldapsource) SearchEntry(name, passwd string) (string, bool) {
+func (ls Ldapsource) SearchEntry(name, passwd string) (string, string, string, string, bool) {
l, err := ldapDial(ls)
if err != nil {
log.Error(4, "LDAP Connect error, %s:%v", ls.Host, err)
ls.Enabled = false
- return "", false
+ return "", "", "", "", false
}
defer l.Close()
@@ -65,26 +68,29 @@ func (ls Ldapsource) SearchEntry(name, passwd string) (string, bool) {
err = l.Bind(nx, passwd)
if err != nil {
log.Debug("LDAP Authan failed for %s, reason: %s", nx, err.Error())
- return "", false
+ return "", "", "", "", false
}
search := ldap.NewSearchRequest(
ls.BaseDN,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf(ls.Filter, name),
- []string{ls.Attributes},
+ []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail},
nil)
sr, err := l.Search(search)
if err != nil {
log.Debug("LDAP Authen OK but not in filter %s", name)
- return "", false
+ return "", "", "", "", false
}
log.Debug("LDAP Authen OK: %s", name)
if len(sr.Entries) > 0 {
- r := sr.Entries[0].GetAttributeValue(ls.Attributes)
- return r, true
+ cn := sr.Entries[0].GetAttributeValue(ls.AttributeUsername)
+ name := sr.Entries[0].GetAttributeValue(ls.AttributeName)
+ sn := sr.Entries[0].GetAttributeValue(ls.AttributeSurname)
+ mail := sr.Entries[0].GetAttributeValue(ls.AttributeMail)
+ return cn, name, sn, mail, true
}
- return "", true
+ return "", "", "", "", true
}
func ldapDial(ls Ldapsource) (*ldap.Conn, error) {
diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go
index 36e62f04..2902a92f 100644
--- a/modules/auth/repo_form.go
+++ b/modules/auth/repo_form.go
@@ -31,7 +31,7 @@ func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) bin
}
type MigrateRepoForm struct {
- HttpsUrl string `form:"url" binding:"Required;Url"`
+ CloneAddr string `binding:"Required"`
AuthUserName string `form:"auth_username"`
AuthPasswd string `form:"auth_password"`
Uid int64 `form:"uid" binding:"Required"`
@@ -52,7 +52,6 @@ type RepoSettingForm struct {
Branch string `form:"branch"`
Interval int `form:"interval"`
Private bool `form:"private"`
- GoGet bool `form:"goget"`
}
func (f *RepoSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go
index 3c0ff651..b616a460 100644
--- a/modules/auth/user_form.go
+++ b/modules/auth/user_form.go
@@ -99,7 +99,7 @@ func (f *UploadAvatarForm) Validate(ctx *macaron.Context, errs binding.Errors) b
}
type AddEmailForm struct {
- Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
+ Email string `binding:"Required;Email;MaxSize(50)"`
}
func (f *AddEmailForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
diff --git a/modules/base/template.go b/modules/base/template.go
index f3fa1385..cfcabb71 100644
--- a/modules/base/template.go
+++ b/modules/base/template.go
@@ -41,6 +41,10 @@ func List(l *list.List) chan interface{} {
return c
}
+func Sha1(str string) string {
+ return EncodeSha1(str)
+}
+
func ShortSha(sha1 string) string {
if len(sha1) == 40 {
return sha1[:10]
@@ -126,8 +130,13 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
return a + b
},
"ActionIcon": ActionIcon,
- "DateFormat": DateFormat,
- "List": List,
+ "DateFmtLong": func(t time.Time) string {
+ return t.Format(time.RFC1123Z)
+ },
+ "DateFmtShort": func(t time.Time) string {
+ return t.Format("Jan 02, 2006")
+ },
+ "List": List,
"Mail2Domain": func(mail string) string {
if !strings.Contains(mail, "@") {
return "try.gogs.io"
@@ -155,6 +164,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
},
"DiffTypeToStr": DiffTypeToStr,
"DiffLineTypeToStr": DiffLineTypeToStr,
+ "Sha1": Sha1,
"ShortSha": ShortSha,
"Md5": EncodeMd5,
"ActionContent2Commits": ActionContent2Commits,
diff --git a/modules/base/tool.go b/modules/base/tool.go
index 5043364c..55e6dffd 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -126,7 +126,7 @@ func VerifyTimeLimitCode(data string, minutes int, code string) bool {
retCode := CreateTimeLimitCode(data, minutes, start)
if retCode == code && minutes > 0 {
// check time is expired or not
- before, _ := DateParse(start, "YmdHi")
+ before, _ := time.ParseInLocation("200601021504", start, time.Local)
now := time.Now()
if before.Add(time.Minute*time.Duration(minutes)).Unix() > now.Unix() {
return true
@@ -141,7 +141,7 @@ const TimeLimitCodeLength = 12 + 6 + 40
// create a time limit code
// code format: 12 length date time string + 6 minutes string + 40 sha1 encoded string
func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string {
- format := "YmdHi"
+ format := "200601021504"
var start, end time.Time
var startStr, endStr string
@@ -149,16 +149,16 @@ func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string
if startInf == nil {
// Use now time create code
start = time.Now()
- startStr = DateFormat(start, format)
+ startStr = start.Format(format)
} else {
// use start string create code
startStr = startInf.(string)
- start, _ = DateParse(startStr, format)
- startStr = DateFormat(start, format)
+ start, _ = time.ParseInLocation(format, startStr, time.Local)
+ startStr = start.Format(format)
}
end = start.Add(time.Minute * time.Duration(minutes))
- endStr = DateFormat(end, format)
+ endStr = end.Format(format)
// create sha1 encode string
sh := sha1.New()
@@ -420,58 +420,3 @@ func Subtract(left interface{}, right interface{}) interface{} {
return fleft + float64(rleft) - (fright + float64(rright))
}
}
-
-// DateFormat pattern rules.
-var datePatterns = []string{
- // year
- "Y", "2006", // A full numeric representation of a year, 4 digits Examples: 1999 or 2003
- "y", "06", //A two digit representation of a year Examples: 99 or 03
-
- // month
- "m", "01", // Numeric representation of a month, with leading zeros 01 through 12
- "n", "1", // Numeric representation of a month, without leading zeros 1 through 12
- "M", "Jan", // A short textual representation of a month, three letters Jan through Dec
- "F", "January", // A full textual representation of a month, such as January or March January through December
-
- // day
- "d", "02", // Day of the month, 2 digits with leading zeros 01 to 31
- "j", "2", // Day of the month without leading zeros 1 to 31
-
- // week
- "D", "Mon", // A textual representation of a day, three letters Mon through Sun
- "l", "Monday", // A full textual representation of the day of the week Sunday through Saturday
-
- // time
- "g", "3", // 12-hour format of an hour without leading zeros 1 through 12
- "G", "15", // 24-hour format of an hour without leading zeros 0 through 23
- "h", "03", // 12-hour format of an hour with leading zeros 01 through 12
- "H", "15", // 24-hour format of an hour with leading zeros 00 through 23
-
- "a", "pm", // Lowercase Ante meridiem and Post meridiem am or pm
- "A", "PM", // Uppercase Ante meridiem and Post meridiem AM or PM
-
- "i", "04", // Minutes with leading zeros 00 to 59
- "s", "05", // Seconds, with leading zeros 00 through 59
-
- // time zone
- "T", "MST",
- "P", "-07:00",
- "O", "-0700",
-
- // RFC 2822
- "r", time.RFC1123Z,
-}
-
-// Parse Date use PHP time format.
-func DateParse(dateString, format string) (time.Time, error) {
- replacer := strings.NewReplacer(datePatterns...)
- format = replacer.Replace(format)
- return time.ParseInLocation(format, dateString, time.Local)
-}
-
-// Date takes a PHP like date func to Go's time format.
-func DateFormat(t time.Time, format string) string {
- replacer := strings.NewReplacer(datePatterns...)
- format = replacer.Replace(format)
- return t.Format(format)
-}
diff --git a/modules/git/signature.go b/modules/git/signature.go
index 20f647d2..ad9c1b39 100644
--- a/modules/git/signature.go
+++ b/modules/git/signature.go
@@ -17,24 +17,35 @@ type Signature struct {
When time.Time
}
-// Helper to get a signature from the commit line, which looks like this:
+// Helper to get a signature from the commit line, which looks like these:
// author Patrick Gundlach <gundlach@speedata.de> 1378823654 +0200
+// author Patrick Gundlach <gundlach@speedata.de> Thu, 07 Apr 2005 22:13:13 +0200
// but without the "author " at the beginning (this method should)
// be used for author and committer.
//
-// FIXME: include timezone!
-func newSignatureFromCommitline(line []byte) (*Signature, error) {
+// FIXME: include timezone for timestamp!
+func newSignatureFromCommitline(line []byte) (_ *Signature, err error) {
sig := new(Signature)
emailstart := bytes.IndexByte(line, '<')
sig.Name = string(line[:emailstart-1])
emailstop := bytes.IndexByte(line, '>')
sig.Email = string(line[emailstart+1 : emailstop])
- timestop := bytes.IndexByte(line[emailstop+2:], ' ')
- timestring := string(line[emailstop+2 : emailstop+2+timestop])
- seconds, err := strconv.ParseInt(timestring, 10, 64)
- if err != nil {
- return nil, err
+
+ // Check date format.
+ firstChar := line[emailstop+2]
+ if firstChar >= 48 && firstChar <= 57 {
+ timestop := bytes.IndexByte(line[emailstop+2:], ' ')
+ timestring := string(line[emailstop+2 : emailstop+2+timestop])
+ seconds, err := strconv.ParseInt(timestring, 10, 64)
+ if err != nil {
+ return nil, err
+ }
+ sig.When = time.Unix(seconds, 0)
+ } else {
+ sig.When, err = time.Parse(time.RFC1123Z, string(line[emailstop+2:]))
+ if err != nil {
+ return nil, err
+ }
}
- sig.When = time.Unix(seconds, 0)
return sig, nil
}
diff --git a/modules/mailer/mailer.go b/modules/mailer/mailer.go
index 6a23e5d0..fc6ec2fa 100644
--- a/modules/mailer/mailer.go
+++ b/modules/mailer/mailer.go
@@ -10,6 +10,7 @@ import (
"net"
"net/mail"
"net/smtp"
+ "os"
"strings"
"github.com/gogits/gogs/modules/log"
@@ -95,6 +96,15 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte)
return err
}
+ hostname, err := os.Hostname()
+ if err != nil {
+ return err
+ }
+
+ if err = client.Hello(hostname); err != nil {
+ return err
+ }
+
// If not using SMTPS, alway use STARTTLS if available
hasStartTLS, _ := client.Extension("STARTTLS")
if !isSecureConn && hasStartTLS {
diff --git a/modules/middleware/context.go b/modules/middleware/context.go
index 28be3a30..45779d58 100644
--- a/modules/middleware/context.go
+++ b/modules/middleware/context.go
@@ -130,6 +130,18 @@ func (ctx *Context) Handle(status int, title string, err error) {
ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status)))
}
+func (ctx *Context) HandleAPI(status int, obj interface{}) {
+ var message string
+ if err, ok := obj.(error); ok {
+ message = err.Error()
+ } else {
+ message = obj.(string)
+ }
+ ctx.JSON(status, map[string]string{
+ "message": message,
+ })
+}
+
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
modtime := time.Now()
for _, p := range params {
diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go
index 1ab158dd..67a9eda6 100644
--- a/modules/middleware/repo.go
+++ b/modules/middleware/repo.go
@@ -394,8 +394,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
}
ctx.Data["CloneLink"] = ctx.Repo.CloneLink
- if ctx.Repo.Repository.IsGoget {
- ctx.Data["GoGetLink"] = fmt.Sprintf("%s%s/%s", setting.AppUrl, u.LowerName, repo.LowerName)
+ if ctx.Query("go-get") == "1" {
ctx.Data["GoGetImport"] = fmt.Sprintf("%s/%s/%s", setting.Domain, u.LowerName, repo.LowerName)
}
diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css
index 9f6cf12f..43931e94 100644
--- a/public/ng/css/gogs.css
+++ b/public/ng/css/gogs.css
@@ -1066,9 +1066,6 @@ The register and sign-in page style
#repo-header-download-drop .btn > i {
margin-right: 6px;
}
-#repo-header-download-drop input {
- cursor: default;
-}
#repo-header-download-drop button,
#repo-header-download-drop input {
font-size: 11px;
@@ -1089,6 +1086,7 @@ The register and sign-in page style
border-right: none;
width: 190px;
border-left: none;
+ cursor: default;
}
#repo-clone-help {
clear: both;
diff --git a/public/ng/js/gogs.js b/public/ng/js/gogs.js
index a6b9753e..c5fd719c 100644
--- a/public/ng/js/gogs.js
+++ b/public/ng/js/gogs.js
@@ -209,27 +209,28 @@ var Gogs = {};
$list.parents('tr').removeClass('end-selected-line');
$list.parents('tr').find('td').removeClass('selected-line');
if ($from) {
- var expr = new RegExp(/diff-(\d+)L(\d+)/);
+ var expr = new RegExp(/diff-(\w+)([LR]\d+)/);
var selectMatches = $select.attr('rel').match(expr)
var fromMatches = $from.attr('rel').match(expr)
- var a = parseInt(selectMatches[2]);
- var b = parseInt(fromMatches[2]);
- var linesIntToStr = {};
- linesIntToStr[a] = selectMatches[2];
- linesIntToStr[b] = fromMatches[2];
-
- var c;
- if (a != b) {
- if (a > b) {
- c = a;
- a = b;
- b = c;
+ var selectTop = $select.offset().top;
+ var fromTop = $from.offset().top;
+ var hash;
+
+ if (selectMatches[2] != fromMatches[2]) {
+ if ((selectTop > fromTop)) {
+ $startElem = $from;
+ $endElem = $select;
+ hash = fromMatches[1]+fromMatches[2] + '-' + selectMatches[2];
+ } else {
+ $startElem = $select;
+ $endElem = $from;
+ hash = selectMatches[1]+selectMatches[2] + '-' + fromMatches[2];
}
- $('[rel=diff-'+fromMatches[1]+'L' + linesIntToStr[b] + ']').parents('tr').next().addClass('end-selected-line');
- var $selectedLines = $('[rel=diff-'+fromMatches[1]+'L' + linesIntToStr[a] + ']').parents('tr').nextUntil('.end-selected-line').andSelf();
+ $endElem.parents('tr').next().addClass('end-selected-line');
+ var $selectedLines = $startElem.parents('tr').nextUntil('.end-selected-line').andSelf();
$selectedLines.find('td.lines-num > span').addClass('active')
$selectedLines.find('td').addClass('selected-line');
- $.changeHash('#diff-'+fromMatches[1]+'L' + linesIntToStr[a] + '-L' + linesIntToStr[b]);
+ $.changeHash('#diff-'+hash);
return
}
}
@@ -262,7 +263,7 @@ var Gogs = {};
});
$(window).on('hashchange', function (e) {
- var m = window.location.hash.match(/^#diff-(\d+)(L\d+)\-(L\d+)$/);
+ var m = window.location.hash.match(/^#diff-(\w+)([LR]\d+)\-([LR]\d+)$/);
var $list = $('.code-diff td.lines-num > span');
var $first;
if (m) {
@@ -271,7 +272,7 @@ var Gogs = {};
$("html, body").scrollTop($first.offset().top - 200);
return;
}
- m = window.location.hash.match(/^#diff-(\d+)(L\d+)$/);
+ m = window.location.hash.match(/^#diff-(\w+)([LR]\d+)$/);
if (m) {
$first = $list.filter('[rel=diff-' + m[1] + m[2] + ']');
selectRange($list, $first);
diff --git a/public/ng/less/gogs/repository.less b/public/ng/less/gogs/repository.less
index d683d033..63c25d06 100644
--- a/public/ng/less/gogs/repository.less
+++ b/public/ng/less/gogs/repository.less
@@ -81,9 +81,6 @@
.btn>i {
margin-right: 6px;
}
- input {
- cursor: default;
- }
button, input {
font-size: 11px;
}
@@ -104,6 +101,7 @@
border-right: none;
width: 190px;
border-left: none;
+ cursor: default;
}
#repo-clone-help {
clear: both;
diff --git a/routers/admin/auths.go b/routers/admin/auths.go
index e537572b..dcb98d33 100644
--- a/routers/admin/auths.go
+++ b/routers/admin/auths.go
@@ -63,15 +63,18 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
case models.LDAP:
u = &models.LDAPConfig{
Ldapsource: ldap.Ldapsource{
- Host: form.Host,
- Port: form.Port,
- UseSSL: form.UseSSL,
- BaseDN: form.BaseDN,
- Attributes: form.Attributes,
- Filter: form.Filter,
- MsAdSAFormat: form.MsAdSA,
- Enabled: true,
- Name: form.AuthName,
+ Host: form.Host,
+ Port: form.Port,
+ UseSSL: form.UseSSL,
+ BaseDN: form.BaseDN,
+ AttributeUsername: form.AttributeUsername,
+ AttributeName: form.AttributeName,
+ AttributeSurname: form.AttributeSurname,
+ AttributeMail: form.AttributeMail,
+ Filter: form.Filter,
+ MsAdSAFormat: form.MsAdSA,
+ Enabled: true,
+ Name: form.AuthName,
},
}
case models.SMTP:
@@ -142,15 +145,18 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
case models.LDAP:
config = &models.LDAPConfig{
Ldapsource: ldap.Ldapsource{
- Host: form.Host,
- Port: form.Port,
- UseSSL: form.UseSSL,
- BaseDN: form.BaseDN,
- Attributes: form.Attributes,
- Filter: form.Filter,
- MsAdSAFormat: form.MsAdSA,
- Enabled: true,
- Name: form.AuthName,
+ Host: form.Host,
+ Port: form.Port,
+ UseSSL: form.UseSSL,
+ BaseDN: form.BaseDN,
+ AttributeUsername: form.AttributeUsername,
+ AttributeName: form.AttributeName,
+ AttributeSurname: form.AttributeSurname,
+ AttributeMail: form.AttributeMail,
+ Filter: form.Filter,
+ MsAdSAFormat: form.MsAdSA,
+ Enabled: true,
+ Name: form.AuthName,
},
}
case models.SMTP:
diff --git a/routers/api/v1/repo.go b/routers/api/v1/repo.go
index fbf9c73e..fde184d9 100644
--- a/routers/api/v1/repo.go
+++ b/routers/api/v1/repo.go
@@ -5,7 +5,7 @@
package v1
import (
- "fmt"
+ "net/url"
"path"
"strings"
@@ -156,17 +156,15 @@ func CreateOrgRepo(ctx *middleware.Context, opt api.CreateRepoOption) {
func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
u, err := models.GetUserByName(ctx.Query("username"))
if err != nil {
- ctx.JSON(500, map[string]interface{}{
- "ok": false,
- "error": err.Error(),
- })
+ if err == models.ErrUserNotExist {
+ ctx.HandleAPI(422, err)
+ } else {
+ ctx.HandleAPI(500, err)
+ }
return
}
if !u.ValidtePassword(ctx.Query("password")) {
- ctx.JSON(500, map[string]interface{}{
- "ok": false,
- "error": "username or password is not correct",
- })
+ ctx.HandleAPI(422, "Username or password is not correct.")
return
}
@@ -175,56 +173,59 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
if form.Uid != u.Id {
org, err := models.GetUserById(form.Uid)
if err != nil {
- log.Error(4, "GetUserById: %v", err)
- ctx.Error(500)
+ if err == models.ErrUserNotExist {
+ ctx.HandleAPI(422, err)
+ } else {
+ ctx.HandleAPI(500, err)
+ }
return
}
ctxUser = org
}
if ctx.HasError() {
- ctx.JSON(422, map[string]interface{}{
- "ok": false,
- "error": ctx.GetErrMsg(),
- })
+ ctx.HandleAPI(422, ctx.GetErrMsg())
return
}
if ctxUser.IsOrganization() {
// Check ownership of organization.
if !ctxUser.IsOwnedBy(u.Id) {
- ctx.JSON(403, map[string]interface{}{
- "ok": false,
- "error": "given user is not owner of organization",
- })
+ ctx.HandleAPI(403, "Given user is not owner of organization.")
return
}
}
- authStr := strings.Replace(fmt.Sprintf("://%s:%s",
- form.AuthUserName, form.AuthPasswd), "@", "%40", -1)
- url := strings.Replace(form.HttpsUrl, "://", authStr+"@", 1)
- repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private,
- form.Mirror, url)
- if err == nil {
- log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
- ctx.JSON(200, map[string]interface{}{
- "ok": true,
- "data": "/" + ctxUser.Name + "/" + form.RepoName,
- })
+ // Remote address can be HTTPS URL or local path.
+ remoteAddr := form.CloneAddr
+ if strings.HasPrefix(form.CloneAddr, "http") {
+ u, err := url.Parse(form.CloneAddr)
+ if err != nil {
+ ctx.HandleAPI(422, err)
+ return
+ }
+ if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 {
+ u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd)
+ }
+ remoteAddr = u.String()
+ } else if !com.IsDir(remoteAddr) {
+ ctx.HandleAPI(422, "Invalid local path, it does not exist or not a directory.")
return
}
- if repo != nil {
- if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
- log.Error(4, "DeleteRepository: %v", errDelete)
+ repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr)
+ if err != nil {
+ if repo != nil {
+ if errDelete := models.DeleteRepository(ctxUser.Id, repo.Id, ctxUser.Name); errDelete != nil {
+ log.Error(4, "DeleteRepository: %v", errDelete)
+ }
}
+ ctx.HandleAPI(500, err)
+ return
}
- ctx.JSON(500, map[string]interface{}{
- "ok": false,
- "error": err.Error(),
- })
+ log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
+ ctx.WriteHeader(200)
}
// GET /user/repos
diff --git a/routers/org/setting.go b/routers/org/setting.go
index 41ec4a21..c638a032 100644
--- a/routers/org/setting.go
+++ b/routers/org/setting.go
@@ -39,18 +39,18 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
// Check if organization name has been changed.
if org.Name != form.OrgUserName {
- isExist, err := models.IsUserExist(form.OrgUserName)
+ isExist, err := models.IsUserExist(org.Id, form.OrgUserName)
if err != nil {
ctx.Handle(500, "IsUserExist", err)
return
} else if isExist {
+ ctx.Data["Err_UserName"] = true
ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SETTINGS_OPTIONS, &form)
return
} else if err = models.ChangeUserName(org, form.OrgUserName); err != nil {
if err == models.ErrUserNameIllegal {
- ctx.Flash.Error(ctx.Tr("form.illegal_username"))
- ctx.Redirect(setting.AppSubUrl + "/org/" + org.LowerName + "/settings")
- return
+ ctx.Data["Err_UserName"] = true
+ ctx.RenderWithErr(ctx.Tr("form.illegal_username"), SETTINGS_OPTIONS, &form)
} else {
ctx.Handle(500, "ChangeUserName", err)
}
@@ -68,7 +68,12 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
org.Avatar = base.EncodeMd5(form.Avatar)
org.AvatarEmail = form.Avatar
if err := models.UpdateUser(org); err != nil {
- ctx.Handle(500, "UpdateUser", err)
+ if err == models.ErrEmailAlreadyUsed {
+ ctx.Data["Err_Email"] = true
+ ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_OPTIONS, &form)
+ } else {
+ ctx.Handle(500, "UpdateUser", err)
+ }
return
}
log.Trace("Organization setting updated: %s", org.Name)
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 3e0206da..722bd0c3 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -549,6 +549,7 @@ func UpdateIssueLabel(ctx *middleware.Context) {
label.NumClosedIssues--
}
}
+
if err = models.UpdateLabel(label); err != nil {
ctx.Handle(500, "issue.UpdateIssueLabel(UpdateLabel)", err)
return
@@ -767,6 +768,24 @@ func Comment(ctx *middleware.Context) {
return
}
+ if err = issue.GetLabels(); err != nil {
+ send(500, nil, err)
+ return
+ }
+
+ for _, label := range issue.Labels {
+ if issue.IsClosed {
+ label.NumClosedIssues++
+ } else {
+ label.NumClosedIssues--
+ }
+
+ if err = models.UpdateLabel(label); err != nil {
+ send(500, nil, err)
+ return
+ }
+ }
+
// Change open/closed issue counter for the associated milestone
if issue.MilestoneId > 0 {
if err = models.ChangeMilestoneIssueStats(issue); err != nil {
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 48f7b09b..dfd827bb 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -181,20 +181,26 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
}
}
- u, err := url.Parse(form.HttpsUrl)
-
- if err != nil || u.Scheme != "https" {
- ctx.Data["Err_HttpsUrl"] = true
- ctx.RenderWithErr(ctx.Tr("form.url_error"), MIGRATE, &form)
+ // Remote address can be HTTPS URL or local path.
+ remoteAddr := form.CloneAddr
+ if strings.HasPrefix(form.CloneAddr, "http") {
+ u, err := url.Parse(form.CloneAddr)
+ if err != nil {
+ ctx.Data["Err_CloneAddr"] = true
+ ctx.RenderWithErr(ctx.Tr("form.url_error"), MIGRATE, &form)
+ return
+ }
+ if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 {
+ u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd)
+ }
+ remoteAddr = u.String()
+ } else if !com.IsDir(remoteAddr) {
+ ctx.Data["Err_CloneAddr"] = true
+ ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_local_path"), MIGRATE, &form)
return
}
- if len(form.AuthUserName) > 0 || len(form.AuthPasswd) > 0 {
- u.User = url.UserPassword(form.AuthUserName, form.AuthPasswd)
- }
-
- repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private,
- form.Mirror, u.String())
+ repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr)
if err == nil {
log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName)
diff --git a/routers/repo/setting.go b/routers/repo/setting.go
index 33bf1eab..b40ef2d9 100644
--- a/routers/repo/setting.go
+++ b/routers/repo/setting.go
@@ -8,9 +8,9 @@ import (
"encoding/json"
"errors"
"fmt"
+ "path"
"strings"
"time"
- "path"
"github.com/Unknwon/com"
@@ -84,7 +84,6 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
ctx.Repo.Repository.Description = form.Description
ctx.Repo.Repository.Website = form.Website
ctx.Repo.Repository.IsPrivate = form.Private
- ctx.Repo.Repository.IsGoget = form.GoGet
if err := models.UpdateRepository(ctx.Repo.Repository); err != nil {
ctx.Handle(404, "UpdateRepository", err)
return
@@ -110,7 +109,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
}
newOwner := ctx.Query("new_owner_name")
- isExist, err := models.IsUserExist(newOwner)
+ isExist, err := models.IsUserExist(0, newOwner)
if err != nil {
ctx.Handle(500, "IsUserExist", err)
return
diff --git a/routers/user/auth.go b/routers/user/auth.go
index 9ed44e35..5dacaf8c 100644
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -351,15 +351,12 @@ func ActivateEmail(ctx *middleware.Context) {
// Verify code.
if email := models.VerifyActiveEmailCode(code, email_string); email != nil {
- err := email.Activate()
- if err != nil {
+ if err := email.Activate(); err != nil {
ctx.Handle(500, "ActivateEmail", err)
}
log.Trace("Email activated: %s", email.Email)
-
ctx.Flash.Success(ctx.Tr("settings.activate_email_success"))
-
}
ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
diff --git a/routers/user/setting.go b/routers/user/setting.go
index 953e6113..a44d3b7e 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -50,7 +50,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
// Check if user name has been changed.
if ctx.User.Name != form.UserName {
- isExist, err := models.IsUserExist(form.UserName)
+ isExist, err := models.IsUserExist(ctx.User.Id, form.UserName)
if err != nil {
ctx.Handle(500, "IsUserExist", err)
return
@@ -58,11 +58,14 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SETTINGS_PROFILE, &form)
return
} else if err = models.ChangeUserName(ctx.User, form.UserName); err != nil {
- if err == models.ErrUserNameIllegal {
+ switch err {
+ case models.ErrUserNameIllegal:
ctx.Flash.Error(ctx.Tr("form.illegal_username"))
ctx.Redirect(setting.AppSubUrl + "/user/settings")
- return
- } else {
+ case models.ErrEmailAlreadyUsed:
+ ctx.Flash.Error(ctx.Tr("form.email_been_used"))
+ ctx.Redirect(setting.AppSubUrl + "/user/settings")
+ default:
ctx.Handle(500, "ChangeUserName", err)
}
return
@@ -133,13 +136,12 @@ func SettingsEmails(ctx *middleware.Context) {
ctx.Data["PageIsUserSettings"] = true
ctx.Data["PageIsSettingsEmails"] = true
- var err error
- ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id)
-
+ emails, err := models.GetEmailAddresses(ctx.User.Id)
if err != nil {
- ctx.Handle(500, "email.GetEmailAddresses", err)
+ ctx.Handle(500, "GetEmailAddresses", err)
return
}
+ ctx.Data["Emails"] = emails
ctx.HTML(200, SETTINGS_EMAILS)
}
@@ -149,16 +151,16 @@ func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
ctx.Data["PageIsUserSettings"] = true
ctx.Data["PageIsSettingsEmails"] = true
- var err error
- ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id)
+ emails, err := models.GetEmailAddresses(ctx.User.Id)
if err != nil {
- ctx.Handle(500, "email.GetEmailAddresses", err)
+ ctx.Handle(500, "GetEmailAddresses", err)
return
}
+ ctx.Data["Emails"] = emails
- // Delete Email address.
+ // Delete E-mail address.
if ctx.Query("_method") == "DELETE" {
- id := com.StrTo(ctx.Query("id")).MustInt64()
+ id := ctx.QueryInt64("id")
if id <= 0 {
return
}
@@ -174,7 +176,7 @@ func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
// Make emailaddress primary.
if ctx.Query("_method") == "PRIMARY" {
- id := com.StrTo(ctx.Query("id")).MustInt64()
+ id := ctx.QueryInt64("id")
if id <= 0 {
return
}
@@ -189,46 +191,41 @@ func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) {
}
// Add Email address.
- if ctx.Req.Method == "POST" {
- if ctx.HasError() {
- ctx.HTML(200, SETTINGS_EMAILS)
- return
- }
+ if ctx.HasError() {
+ ctx.HTML(200, SETTINGS_EMAILS)
+ return
+ }
- cleanEmail := strings.Replace(form.Email, "\n", "", -1)
- e := &models.EmailAddress{
- Uid: ctx.User.Id,
- Email: cleanEmail,
- IsActivated: !setting.Service.RegisterEmailConfirm,
- }
+ cleanEmail := strings.Replace(form.Email, "\n", "", -1)
+ e := &models.EmailAddress{
+ Uid: ctx.User.Id,
+ Email: cleanEmail,
+ IsActivated: !setting.Service.RegisterEmailConfirm,
+ }
- if err := models.AddEmailAddress(e); err != nil {
- if err == models.ErrEmailAlreadyUsed {
- ctx.RenderWithErr(ctx.Tr("form.email_has_been_used"), SETTINGS_EMAILS, &form)
- return
- }
- ctx.Handle(500, "email.AddEmailAddress", err)
+ if err := models.AddEmailAddress(e); err != nil {
+ if err == models.ErrEmailAlreadyUsed {
+ ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_EMAILS, &form)
return
- } else {
-
- // Send confirmation e-mail
- if setting.Service.RegisterEmailConfirm {
- mailer.SendActivateEmail(ctx.Render, ctx.User, e)
+ }
+ ctx.Handle(500, "AddEmailAddress", err)
+ return
+ } else {
+ // Send confirmation e-mail
+ if setting.Service.RegisterEmailConfirm {
+ mailer.SendActivateEmail(ctx.Render, ctx.User, e)
- if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
- log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
- }
- ctx.Flash.Success(ctx.Tr("settings.add_email_success_confirmation_email_sent"))
- } else {
- ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
+ if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
+ log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
}
-
- log.Trace("Email address added: %s", e.Email)
-
- ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
- return
+ ctx.Flash.Success(ctx.Tr("settings.add_email_success_confirmation_email_sent"))
+ } else {
+ ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
}
+ log.Trace("Email address added: %s", e.Email)
+ ctx.Redirect(setting.AppSubUrl + "/user/settings/email")
+ return
}
ctx.HTML(200, SETTINGS_EMAILS)
diff --git a/scripts/less.sh b/scripts/less.sh
new file mode 100755
index 00000000..ff2f5736
--- /dev/null
+++ b/scripts/less.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo "compiling LESS Files"
+lessc ../public/ng/less/gogs.less ../public/ng/css/gogs.css
+lessc ../public/ng/less/ui.less ../public/ng/css/ui.css
+echo "done"
diff --git a/templates/.VERSION b/templates/.VERSION
index 0c9421a4..b9cd4a18 100644
--- a/templates/.VERSION
+++ b/templates/.VERSION
@@ -1 +1 @@
-0.5.13.0214 Beta \ No newline at end of file
+0.5.14.0222 Beta \ No newline at end of file
diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl
index 77d28f62..e1bbd23d 100644
--- a/templates/admin/auth/edit.tmpl
+++ b/templates/admin/auth/edit.tmpl
@@ -48,8 +48,20 @@
<input class="ipt ipt-large ipt-radius {{if .Err_BaseDN}}ipt-error{{end}}" id="base_dn" name="base_dn" value="{{.Source.LDAP.BaseDN}}" />
</div>
<div class="field">
- <label class="req" for="attributes">{{.i18n.Tr "admin.auths.attributes"}}</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attributes" name="attributes" value="{{.Source.LDAP.Attributes}}" />
+ <label class="req" for="attribute_username">{{.i18n.Tr "admin.auths.attribute_username"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attribute_username" name="attribute_username" value="{{.Source.LDAP.AttributeUsername}}" />
+ </div>
+ <div class="field">
+ <label class="req" for="attribute_name">{{.i18n.Tr "admin.auths.attribute_name"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attribute_name" name="attribute_name" value="{{.Source.LDAP.AttributeName}}" />
+ </div>
+ <div class="field">
+ <label class="req" for="attribute_surname">{{.i18n.Tr "admin.auths.attribute_surname"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attribute_surname" name="attribute_surname" value="{{.Source.LDAP.AttributeSurname}}" />
+ </div>
+ <div class="field">
+ <label class="req" for="attribute_mail">{{.i18n.Tr "admin.auths.attribute_mail"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attribute_mail" name="attribute_mail" value="{{.Source.LDAP.AttributeMail}}" />
</div>
<div class="field">
<label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label>
diff --git a/templates/admin/auth/list.tmpl b/templates/admin/auth/list.tmpl
index aba516b8..ec701a8f 100644
--- a/templates/admin/auth/list.tmpl
+++ b/templates/admin/auth/list.tmpl
@@ -34,8 +34,8 @@
<td><a href="{{AppSubUrl}}/admin/auths/{{.Id}}">{{.Name}}</a></td>
<td>{{.TypeString}}</td>
<td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td>
- <td><span title="{{DateFormat .Updated "r"}}">{{DateFormat .Updated "M d, Y"}}</span></td>
- <td><span title="{{DateFormat .Created "r"}}">{{DateFormat .Created "M d, Y"}}</span></td>
+ <td><span title="{{DateFmtLong .Updated}}">{{DateFmtShort .Updated}}</span></td>
+ <td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
<td><a href="{{AppSubUrl}}/admin/auths/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td>
</tr>
{{end}}
diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl
index b522dc08..ce5083a0 100644
--- a/templates/admin/org/list.tmpl
+++ b/templates/admin/org/list.tmpl
@@ -35,7 +35,7 @@
<td>{{.NumTeams}}</td>
<td>{{.NumMembers}}</td>
<td>{{.NumRepos}}</td>
- <td><span title="{{DateFormat .Created "r"}}">{{DateFormat .Created "M d, Y"}}</span></td>
+ <td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
</tr>
{{end}}
</tbody>
diff --git a/templates/admin/repo/list.tmpl b/templates/admin/repo/list.tmpl
index 88e16a43..981e2ef7 100644
--- a/templates/admin/repo/list.tmpl
+++ b/templates/admin/repo/list.tmpl
@@ -37,7 +37,7 @@
<td>{{.NumWatches}}</td>
<td>{{.NumStars}}</td>
<td>{{.NumIssues}}</td>
- <td><span title="{{DateFormat .Created "r"}}">{{DateFormat .Created "M d, Y"}}</span></td>
+ <td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
</tr>
{{end}}
</tbody>
diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl
index d42d5291..1dd5553e 100644
--- a/templates/admin/user/list.tmpl
+++ b/templates/admin/user/list.tmpl
@@ -37,7 +37,7 @@
<td><i class="fa fa{{if .IsActive}}-check{{end}}-square-o"></i></td>
<td><i class="fa fa{{if .IsAdmin}}-check{{end}}-square-o"></i></td>
<td>{{.NumRepos}}</td>
- <td><span title="{{DateFormat .Created "r"}}">{{DateFormat .Created "M d, Y"}}</span></td>
+ <td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created }}</span></td>
<td><a href="{{AppSubUrl}}/admin/users/{{.Id}}"><i class="fa fa-pencil-square-o"></i></a></td>
</tr>
{{end}}
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index 7775933c..cb3951ea 100644
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -9,7 +9,7 @@
<meta name="description" content="Gogs(Go Git Service) is a GitHub-like clone in the Go Programming Language" />
<meta name="keywords" content="go, git">
<meta name="_csrf" content="{{.CsrfToken}}" />
- {{if .Repository.IsGoget}}<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">{{end}}
+ {{if .GoGetImport}}<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">{{end}}
<!-- Stylesheets -->
{{if CdnMode}}
diff --git a/templates/ng/base/head.tmpl b/templates/ng/base/head.tmpl
index 40a7d28f..f2a235bd 100644
--- a/templates/ng/base/head.tmpl
+++ b/templates/ng/base/head.tmpl
@@ -7,7 +7,7 @@
<meta name="description" content="Gogs(Go Git Service) a painless self-hosted Git Service written in Go" />
<meta name="keywords" content="go, git, self-hosted, gogs">
<meta name="_csrf" content="{{.CsrfToken}}" />
- {{if .Repository.IsGoget}}<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">{{end}}
+ {{if .GoGetImport}}<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">{{end}}
<link rel="shortcut icon" href="{{AppSubUrl}}/img/favicon.png" />
diff --git a/templates/org/base/header.tmpl b/templates/org/base/header.tmpl
index 1bbb092b..1649b920 100644
--- a/templates/org/base/header.tmpl
+++ b/templates/org/base/header.tmpl
@@ -2,7 +2,7 @@
<div class="container">
<a class="text-black left" href="{{AppSubUrl}}/org/{{.Org.LowerName}}">
<img class="avatar-48 left" src="{{.Org.AvatarLink}}?s=100">
- <span class="org-name">{{.Org.FullName}}</span>
+ <span class="org-name">{{if .Org.FullName}}{{.Org.FullName}}{{else}}{{.Org.Name}}{{end}}</span>
</a>
<ul class="menu menu-line container">
<li class="right">
diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl
index bb160b57..df29d61f 100644
--- a/templates/org/home.tmpl
+++ b/templates/org/home.tmpl
@@ -9,85 +9,85 @@
{{if .IsOrganizationOwner}}<a class="text-grey" href="{{.OrgLink}}/settings"><span class="octicon octicon-gear"></span></a>{{end}}
</h2>
{{if .Org.Description}}<p>{{.Org.Description}}</p>{{end}}
- <ul class="text-grey">
- {{if .Org.Location}}<li><span class="octicon octicon-location"></span> <span>{{.Org.Location}}</span></li>{{end}}
- {{if .Org.Website}}<li><span class="octicon octicon-link"></span> <a target="_blank" href="{{.Org.Website}}">{{.Org.Website}}</a></li>{{end}}
- {{if .Org.Email}}<li><span class="octicon octicon-mail"></span> <a href="mailto:{{.Org.Email}}">{{.Org.Email}}</a></li>{{end}}
- </ul>
+ <ul class="text-grey">
+ {{if .Org.Location}}<li><span class="octicon octicon-location"></span> <span>{{.Org.Location}}</span></li>{{end}}
+ {{if .Org.Website}}<li><span class="octicon octicon-link"></span> <a target="_blank" href="{{.Org.Website}}">{{.Org.Website}}</a></li>{{end}}
+ {{if .Org.Email}}<li><span class="octicon octicon-mail"></span> <a href="mailto:{{.Org.Email}}">{{.Org.Email}}</a></li>{{end}}
+ </ul>
</div>
</div>
</div>
<div class="container">
{{$isMember := .Org.IsOrgMember $.SignedUser.Id}}
- <div id="org-home-repo-list" class="left grid-2-3">
- <div class="clear">
- {{if .IsOrganizationOwner}}
- <a class="btn btn-green btn-large btn-link btn-radius right" href="{{AppSubUrl}}/repo/create?org={{.Org.Id}}"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "new_repo"}}</a>
- {{end}}
- </div>
- <div id="org-repo-list">
- {{range .Repos}}
- {{if .HasAccess $.SignedUser.Name}}
- <div class="org-repo-item">
- <ul class="org-repo-status right">
- <li><i class="octicon octicon-star"></i> {{.NumStars}}</li>
- <li><i class="octicon octicon-git-branch"></i> {{.NumForks}}</li>
- </ul>
- <h2><a href="{{AppSubUrl}}/{{$.Org.Name}}/{{.Name}}">{{.Name}}</a></h2>
- <p class="org-repo-description">{{.Description}}</p>
- <p class="org-repo-updated">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p>
- </div>
- {{end}}
+ <div id="org-home-repo-list" class="left grid-2-3">
+ <div class="clear">
+ {{if .IsOrganizationOwner}}
+ <a class="btn btn-green btn-large btn-link btn-radius right" href="{{AppSubUrl}}/repo/create?org={{.Org.Id}}"><i class="octicon octicon-repo-create"></i> {{.i18n.Tr "new_repo"}}</a>
+ {{end}}
+ </div>
+ <div id="org-repo-list">
+ {{range .Repos}}
+ {{if or (not .IsPrivate) (.HasAccess $.SignedUser.Name)}}
+ <div class="org-repo-item">
+ <ul class="org-repo-status right">
+ <li><i class="octicon octicon-star"></i> {{.NumStars}}</li>
+ <li><i class="octicon octicon-git-branch"></i> {{.NumForks}}</li>
+ </ul>
+ <h2><a href="{{AppSubUrl}}/{{$.Org.Name}}/{{.Name}}">{{.Name}}</a></h2>
+ <p class="org-repo-description">{{.Description}}</p>
+ <p class="org-repo-updated">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p>
+ </div>
{{end}}
- </div>
+ {{end}}
</div>
- <div class="grid-1-3 right">
- <div class="org-sidebar">
- <div class="panel panel-radius">
- <div class="panel-header">
- {{if $isMember}}
- <a class="text-grey right" href="{{AppSubUrl}}/org/{{.Org.LowerName}}/members"><strong>{{.Org.NumMembers}}</strong><span class="octicon octicon-chevron-right"></span></a>
- {{end}}
- <strong>{{.i18n.Tr "org.people"}}</strong>
- </div>
- <div class="panel-body member-avatar-group">
- {{range .Members}}
+ </div>
+ <div class="grid-1-3 right">
+ <div class="org-sidebar">
+ <div class="panel panel-radius">
+ <div class="panel-header">
+ {{if $isMember}}
+ <a class="text-grey right" href="{{AppSubUrl}}/org/{{.Org.LowerName}}/members"><strong>{{.Org.NumMembers}}</strong><span class="octicon octicon-chevron-right"></span></a>
+ {{end}}
+ <strong>{{.i18n.Tr "org.people"}}</strong>
+ </div>
+ <div class="panel-body member-avatar-group">
+ {{range .Members}}
{{if or $isMember (.IsPublicMember $.Org.Id)}}
- <a href="{{AppSubUrl}}/{{.Name}}" title="{{.Name}}"><img src="{{.AvatarLink}}"></a>
- {{end}}
+ <a href="{{AppSubUrl}}/{{.Name}}" title="{{.Name}}"><img src="{{.AvatarLink}}"></a>
{{end}}
- </div>
- {{if .IsOrganizationOwner}}
- <div class="panel-footer">
- <a class="btn btn-medium btn-blue btn-link btn-radius" href="{{AppSubUrl}}/org/{{.Org.LowerName}}/invitations/new">{{.i18n.Tr "org.invite_someone"}}</a>
- </div>
- {{end}}
- </div>
- {{if $isMember}}
- <br>
- <div class="panel panel-radius">
- <div class="panel-header">
- <a class="text-grey right" href="{{AppSubUrl}}/org/{{.Org.LowerName}}/teams"><strong>{{.Org.NumTeams}}</strong><span class="octicon octicon-chevron-right"></span></a>
- <strong>{{.i18n.Tr "org.teams"}}</strong>
- </div>
- <div class="panel-body" id="org-home-team-list">
- <ul>
- {{range .Teams}}
- <li>
- <a class="text-black" href="{{AppSubUrl}}/org/{{$.Org.LowerName}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a>
- <p class="team-meta">{{.NumMembers}} {{$.i18n.Tr "org.lower_members"}} · {{.NumRepos}} {{$.i18n.Tr "org.lower_repositories"}}</p>
- </li>
- {{end}}
- </ul>
- </div>
- {{if .IsOrganizationOwner}}
- <div class="panel-footer">
- <a class="btn btn-medium btn-blue btn-link btn-radius" href="{{AppSubUrl}}/org/{{$.Org.LowerName}}/teams/new">{{.i18n.Tr "org.create_new_team"}}</a>
- </div>
- {{end}}
- </div>
- {{end}}
+ {{end}}
+ </div>
+ {{if .IsOrganizationOwner}}
+ <div class="panel-footer">
+ <a class="btn btn-medium btn-blue btn-link btn-radius" href="{{AppSubUrl}}/org/{{.Org.LowerName}}/invitations/new">{{.i18n.Tr "org.invite_someone"}}</a>
+ </div>
+ {{end}}
</div>
- </div>
+ {{if $isMember}}
+ <br>
+ <div class="panel panel-radius">
+ <div class="panel-header">
+ <a class="text-grey right" href="{{AppSubUrl}}/org/{{.Org.LowerName}}/teams"><strong>{{.Org.NumTeams}}</strong><span class="octicon octicon-chevron-right"></span></a>
+ <strong>{{.i18n.Tr "org.teams"}}</strong>
+ </div>
+ <div class="panel-body" id="org-home-team-list">
+ <ul>
+ {{range .Teams}}
+ <li>
+ <a class="text-black" href="{{AppSubUrl}}/org/{{$.Org.LowerName}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a>
+ <p class="team-meta">{{.NumMembers}} {{$.i18n.Tr "org.lower_members"}} · {{.NumRepos}} {{$.i18n.Tr "org.lower_repositories"}}</p>
+ </li>
+ {{end}}
+ </ul>
+ </div>
+ {{if .IsOrganizationOwner}}
+ <div class="panel-footer">
+ <a class="btn btn-medium btn-blue btn-link btn-radius" href="{{AppSubUrl}}/org/{{$.Org.LowerName}}/teams/new">{{.i18n.Tr "org.create_new_team"}}</a>
+ </div>
+ {{end}}
+ </div>
+ {{end}}
+ </div>
+ </div>
</div>
{{template "ng/base/footer" .}} \ No newline at end of file
diff --git a/templates/org/settings/nav.tmpl b/templates/org/settings/nav.tmpl
index 11d32d7f..1285c4ab 100644
--- a/templates/org/settings/nav.tmpl
+++ b/templates/org/settings/nav.tmpl
@@ -1,12 +1,12 @@
<div id="setting-menu" class="grid-1-5 panel panel-radius left">
- <div class="panel-header">
- <strong>{{.i18n.Tr "org.settings"}}</strong>
- </div>
- <div class="panel-body">
- <ul class="menu menu-vertical switching-list grid-1-5 left">
- <li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings">{{.i18n.Tr "org.settings.options"}}</a></li>
- <li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li>
- <li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings/delete">{{.i18n.Tr "org.settings.delete"}}</a></li>
- </ul>
- </div>
+ <div class="panel-header">
+ <strong>{{.i18n.Tr "org.settings"}}</strong>
+ </div>
+ <div class="panel-body">
+ <ul class="menu menu-vertical switching-list grid-1-5 left">
+ <li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings">{{.i18n.Tr "org.settings.options"}}</a></li>
+ <li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li>
+ <li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings/delete">{{.i18n.Tr "org.settings.delete"}}</a></li>
+ </ul>
+ </div>
</div>
diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl
index 1ed7acb5..1179ede6 100644
--- a/templates/org/settings/options.tmpl
+++ b/templates/org/settings/options.tmpl
@@ -2,63 +2,63 @@
{{template "ng/base/header" .}}
{{template "org/base/header" .}}
<div id="setting-wrapper" class="main-wrapper">
- <div id="org-setting" class="container clear">
- {{template "org/settings/nav" .}}
- <div class="grid-4-5 left">
- <div class="setting-content">
- {{template "ng/base/alert" .}}
- <div id="setting-content">
- <div id="user-profile-setting-content" class="panel panel-radius">
- <div class="panel-header">
- <strong>{{.i18n.Tr "org.settings.options"}}</strong>
- </div>
- <form class="form form-align panel-body" id="org-setting-form" action="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings" method="post">
- {{.CsrfTokenHtml}}
- <input type="hidden" name="action" value="update">
- <div class="field">
- <label class="req" for="orgname">{{.i18n.Tr "username"}}</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="orgname" name="uname" value="{{.Org.Name}}" data-orgname="{{.Org.Name}}" required />
- </div>
- <div class="white-popup-block mfp-hide" id="change-orgname-modal">
- <h1 class="text-red">{{.i18n.Tr "org.settings.change_orgname"}}</h1>
- <p>{{.i18n.Tr "org.settings.change_orgname_desc"}}</p>
- <br>
- <button class="btn btn-red btn-large btn-radius" id="change-orgname-submit">{{.i18n.Tr "settings.continue"}}</button>
- <button class="btn btn-large btn-radius popup-modal-dismiss">{{.i18n.Tr "settings.cancel"}}</button>
- </div>
- <div class="field">
- <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" />
- </div>
- <div class="field">
- <label class="req" for="email">{{.i18n.Tr "email"}}</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.Org.Email}}" required />
- </div>
- <div class="field clear">
- <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label>
- <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea>
- </div>
- <div class="field">
- <label for="website">{{.i18n.Tr "org.settings.website"}}</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_Website}}ipt-error{{end}}" id="website" name="website" type="url" value="{{.Org.Website}}" />
- </div>
- <div class="field">
- <label for="location">{{.i18n.Tr "org.settings.location"}}</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" />
- </div>
- <div class="field">
- <label for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.Org.AvatarEmail}}" />
- </div>
- <div class="field">
- <span class="form-label"></span>
- <button class="btn btn-green btn-large btn-radius" id="change-orgname-btn" href="#change-orgname-modal">{{.i18n.Tr "org.settings.update_settings"}}</button>
- </div>
- </form>
- </div>
- </div>
+ <div id="org-setting" class="container clear">
+ {{template "org/settings/nav" .}}
+ <div class="grid-4-5 left">
+ <div class="setting-content">
+ {{template "ng/base/alert" .}}
+ <div id="setting-content">
+ <div id="user-profile-setting-content" class="panel panel-radius">
+ <div class="panel-header">
+ <strong>{{.i18n.Tr "org.settings.options"}}</strong>
</div>
- </div>
- </div>
+ <form class="form form-align panel-body" id="org-setting-form" action="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings" method="post">
+ {{.CsrfTokenHtml}}
+ <input type="hidden" name="action" value="update">
+ <div class="field">
+ <label class="req" for="orgname">{{.i18n.Tr "username"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="orgname" name="uname" value="{{.Org.Name}}" data-orgname="{{.Org.Name}}" required />
+ </div>
+ <div class="white-popup-block mfp-hide" id="change-orgname-modal">
+ <h1 class="text-red">{{.i18n.Tr "org.settings.change_orgname"}}</h1>
+ <p>{{.i18n.Tr "org.settings.change_orgname_desc"}}</p>
+ <br>
+ <button class="btn btn-red btn-large btn-radius" id="change-orgname-submit">{{.i18n.Tr "settings.continue"}}</button>
+ <button class="btn btn-large btn-radius popup-modal-dismiss">{{.i18n.Tr "settings.cancel"}}</button>
+ </div>
+ <div class="field">
+ <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" />
+ </div>
+ <div class="field">
+ <label class="req" for="email">{{.i18n.Tr "email"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.Org.Email}}" required />
+ </div>
+ <div class="field clear">
+ <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label>
+ <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea>
+ </div>
+ <div class="field">
+ <label for="website">{{.i18n.Tr "org.settings.website"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Website}}ipt-error{{end}}" id="website" name="website" type="url" value="{{.Org.Website}}" />
+ </div>
+ <div class="field">
+ <label for="location">{{.i18n.Tr "org.settings.location"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" />
+ </div>
+ <div class="field">
+ <label for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.Org.AvatarEmail}}" />
+ </div>
+ <div class="field">
+ <span class="form-label"></span>
+ <button class="btn btn-green btn-large btn-radius" id="change-orgname-btn" href="#change-orgname-modal">{{.i18n.Tr "org.settings.update_settings"}}</button>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
{{template "ng/base/footer" .}} \ No newline at end of file
diff --git a/templates/repo/bare.tmpl b/templates/repo/bare.tmpl
index 2a1409a6..c050b623 100644
--- a/templates/repo/bare.tmpl
+++ b/templates/repo/bare.tmpl
@@ -23,7 +23,7 @@
<h2>{{.i18n.Tr "repo.clone_this_repo"}}</h2>
<button class="btn btn-blue current left btn-left-radius" id="repo-clone-ssh" data-link="{{.CloneLink.SSH}}">SSH</button>
<button class="btn btn-gray left" id="repo-clone-https" data-link="{{.CloneLink.HTTPS}}">HTTPS</button>
- <input id="repo-clone-url" type="text" class="ipt ipt-disabled left" value="{{.CloneLink.SSH}}" readonly />
+ <input id="repo-clone-url" type="text" class="ipt ipt-disabled left" value="{{.CloneLink.SSH}}" onclick="this.select()" readonly />
<button class="btn btn-black left btn-right-radius" id="repo-clone-copy" data-copy-val="val" data-copy-from="#repo-clone-url">{{.i18n.Tr "repo.copy_link"}}</button>
<p class="text-center" id="repo-clone-help">{{.i18n.Tr "repo.clone_helper" | Str2html}}</p>
<hr/>
@@ -50,4 +50,4 @@ git push -u origin master</code></pre>
</div>
</div>
</div>
-{{template "ng/base/footer" .}} \ No newline at end of file
+{{template "ng/base/footer" .}}
diff --git a/templates/repo/diff.tmpl b/templates/repo/diff.tmpl
index 443e002d..f261da55 100644
--- a/templates/repo/diff.tmpl
+++ b/templates/repo/diff.tmpl
@@ -105,14 +105,14 @@
{{else}}
<table>
<tbody>
- {{range $j, $section := $file.Sections}}
- {{range $k, $line := $section.Lines}}
- <tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$i}} ol-{{$i}}">
+ {{range .Sections}}
+ {{range $k, $line := .Lines}}
+ <tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}">
<td class="lines-num lines-num-old">
- <span rel="diff-{{Add $i 1}}L{{$j}}{{$k}}">{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}</span>
+ <span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}">{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}</span>
</td>
<td class="lines-num lines-num-new">
- <span rel="diff-{{Add $i 1}}L{{$j}}{{$k}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span>
+ <span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span>
</td>
<td class="lines-code">
diff --git a/templates/repo/migrate.tmpl b/templates/repo/migrate.tmpl
index b28d0647..5869be15 100644
--- a/templates/repo/migrate.tmpl
+++ b/templates/repo/migrate.tmpl
@@ -7,8 +7,8 @@
<div class="panel-content">
{{template "ng/base/alert" .}}
<div class="field">
- <label class="req" for="url">HTTPS URL</label>
- <input class="ipt ipt-large ipt-radius {{if .Err_HttpsUrl}}ipt-error{{end}}" id="url" name="url" type="text" value="{{.url}}" required />
+ <label class="req" for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label>
+ <input class="ipt ipt-large ipt-radius {{if .Err_CloneAddr}}ipt-error{{end}}" id="clone_addr" name="clone_addr" type="text" value="{{.clone_addr}}" required />
</div>
<div class="field">
<span class="form-label"></span>
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index 093e9375..41683f84 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -59,11 +59,6 @@
<input class="ipt-chk" id="visibility" name="private" type="checkbox" {{if .Repository.IsPrivate}}checked{{end}} />
<span>{{.i18n.Tr "repo.visiblity_helper" | Str2html}}</span>
</div>
- <div class="field">
- <label for="goget">{{.i18n.Tr "repo.goget_meta"}}</label>
- <input class="ipt-chk" id="goget" name="goget" type="checkbox" {{if .Repository.IsGoget}}checked{{end}} />
- <span>{{.i18n.Tr "repo.goget_meta_helper" | Str2html}}</span>
- </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_settings"}}</button>
diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl
index 44c22123..a18a8b50 100644
--- a/templates/user/profile.tmpl
+++ b/templates/user/profile.tmpl
@@ -28,7 +28,7 @@
{{if .Owner.Website}}
<li class="list-group-item"><i class="octicon octicon-link"></i>&nbsp;&nbsp;<a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li>
{{end}}
- <li class="list-group-item"><i class="octicon octicon-clock"></i>&nbsp;&nbsp;{{.i18n.Tr "user.join_on"}} {{DateFormat .Owner.Created "M d, Y"}}</li>
+ <li class="list-group-item"><i class="octicon octicon-clock"></i>&nbsp;&nbsp;{{.i18n.Tr "user.join_on"}} {{DateFmtShort .Owner.Created}}</li>
</ul>
<hr>
<ul class="list-no-style">
diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl
index ce74ef77..2e766a3d 100644
--- a/templates/user/settings/applications.tmpl
+++ b/templates/user/settings/applications.tmpl
@@ -22,7 +22,7 @@
<i class="fa fa-send fa-2x left"></i>
<div class="ssh-content left">
<p><strong>{{.Name}}</strong></p>
- <p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} <span title="{{DateFormat .Created "r"}}">{{DateFormat .Created "M d, Y"}}</span> — <i class="octicon octicon-info"></i>{{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{DateFormat .Updated "M d, Y"}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i></p>
+ <p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} <span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span> — <i class="octicon octicon-info"></i>{{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{DateFmtShort .Updated}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i></p>
</div>
<a href="{{AppSubUrl}}/user/settings/applications?remove={{.Id}}">
<button class="btn btn-small btn-red btn-radius ssh-btn right">{{$.i18n.Tr "settings.delete_token"}}</button>
diff --git a/templates/user/settings/email.tmpl b/templates/user/settings/email.tmpl
index c99e6a04..ec152c5d 100644
--- a/templates/user/settings/email.tmpl
+++ b/templates/user/settings/email.tmpl
@@ -16,7 +16,7 @@
{{range .Emails}}
<li class="email clear">
<div class="email-content left">
- <p><strong>{{.Email}}</strong> {{if .IsPrimary}} <span class="email-primary">{{$.i18n.Tr "settings.primary"}}</span> {{end}}</p>
+ <p><strong>{{.Email}}</strong> {{if .IsPrimary}} <span class="text-red">{{$.i18n.Tr "settings.primary"}}</span> {{end}}</p>
</div>
{{if not .IsPrimary}}
{{if .IsActivated}}
@@ -24,14 +24,14 @@
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="PRIMARY">
<input name="id" type="hidden" value="{{.Id}}">
- <button class="right email-btn btn btn-green btn-radius btn-small">{{$.i18n.Tr "settings.primary_email"}}</button>
+ <button class="right email-btn btn btn-small btn-green btn-radius">{{$.i18n.Tr "settings.primary_email"}}</button>
</form>
{{end}}
<form action="{{AppSubUrl}}/user/settings/email" method="post">
{{$.CsrfTokenHtml}}
<input name="_method" type="hidden" value="DELETE">
<input name="id" type="hidden" value="{{.Id}}">
- <button class="right email-btn btn btn-red btn-radius btn-small">{{$.i18n.Tr "settings.delete_email"}}</button>
+ <button class="right email-btn btn btn-small btn-red btn-radius" style="margin-right: 5px">{{$.i18n.Tr "settings.delete_email"}}</button>
</form>
{{end}}
</li>
diff --git a/templates/user/settings/social.tmpl b/templates/user/settings/social.tmpl
index b47f883e..f2a30da7 100644
--- a/templates/user/settings/social.tmpl
+++ b/templates/user/settings/social.tmpl
@@ -18,7 +18,7 @@
<div class="ssh-content left">
<p><strong>{{Oauth2Name .Type}}</strong></p>
<p class="print">{{.Identity}}</p>
- <p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} <span title="{{DateFormat .Created "r"}}">{{DateFormat .Created "M d, Y"}}</span> — <i class="octicon octicon-info"></i>{{$.i18n.Tr "settings.last_used"}} {{DateFormat .Updated "M d, Y"}}</i></p>
+ <p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} <span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span> — <i class="octicon octicon-info"></i>{{$.i18n.Tr "settings.last_used"}} {{DateFmtShort .Updated}}</i></p>
</div>
<a class="right btn btn-small btn-red btn-header btn-radius" href="{{AppSubUrl}}/user/settings/social?remove={{.Id}}">{{$.i18n.Tr "settings.unbind"}}</a>
</li>
diff --git a/templates/user/settings/sshkeys.tmpl b/templates/user/settings/sshkeys.tmpl
index 48a4d343..42b76039 100644
--- a/templates/user/settings/sshkeys.tmpl
+++ b/templates/user/settings/sshkeys.tmpl
@@ -23,7 +23,7 @@
<div class="ssh-content left">
<p><strong>{{.Name}}</strong></p>
<p class="print">{{.Fingerprint}}</p>
- <p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} <span title="{{DateFormat .Created "r"}}">{{DateFormat .Created "M d, Y"}}</span> — <i class="octicon octicon-info"></i>{{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span title="{{DateFormat .Updated "r"}}">{{DateFormat .Updated "M d, Y"}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i></p>
+ <p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} <span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span> — <i class="octicon octicon-info"></i>{{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span title="{{DateFmtLong .Updated}}">{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i></p>
</div>
<form action="{{AppSubUrl}}/user/settings/ssh" method="post">
{{$.CsrfTokenHtml}}