diff options
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 @@ -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 " @@ -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> <a target="_blank" href="{{.Owner.Website}}">{{.Owner.Website}}</a></li> {{end}} - <li class="list-group-item"><i class="octicon octicon-clock"></i> {{.i18n.Tr "user.join_on"}} {{DateFormat .Owner.Created "M d, Y"}}</li> + <li class="list-group-item"><i class="octicon octicon-clock"></i> {{.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}} |