Merged conflicts.
|
@ -13,8 +13,7 @@ watch_dirs = [
|
|||
watch_exts = [".go"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
#["go-bindata", "-o=modules/bindata/bindata.go", "-ignore=\\.DS_Store|README", "-pkg=bindata", "conf/..."],
|
||||
["go", "install", "-tags", "sqlite"],# redis memcache cert pam
|
||||
["go", "install", "-tags", "sqlite"],# redis memcache cert pam tidb
|
||||
["go", "build", "-tags", "sqlite"],
|
||||
["./gogs", "web"]
|
||||
]
|
|
@ -5,7 +5,7 @@ RUN echo "deb http://ftp.debian.org/debian/ wheezy-backports main" >> /etc/apt/s
|
|||
apt-get update -qqy && \
|
||||
apt-get install --no-install-recommends -qqy \
|
||||
curl build-essential ca-certificates git \
|
||||
openssh-server rsync libpam-dev && \
|
||||
openssh-server libpam-dev && \
|
||||
apt-get autoclean && \
|
||||
apt-get autoremove && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
|
|
@ -406,6 +406,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(org.Settings).
|
||||
Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
|
||||
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), org.SettingsAvatar)
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", org.Webhooks)
|
||||
|
@ -544,7 +545,7 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Group("/:username", func() {
|
||||
m.Group("/:reponame", func() {
|
||||
m.Get("", repo.Home)
|
||||
m.Get(".git", repo.Home)
|
||||
m.Get("\\.git$", repo.Home)
|
||||
}, ignSignIn, middleware.RepoAssignment(true, true), middleware.RepoRef())
|
||||
|
||||
m.Group("/:reponame", func() {
|
||||
|
|
|
@ -463,26 +463,26 @@ issues.label_deletion_success=Label wurde erfolgreich gelöscht!
|
|||
|
||||
pulls.compare_changes=Änderungen vergleichen
|
||||
pulls.compare_changes_desc=Vergleiche zwei Branches und erstelle einen Pull Request für die Änderungen.
|
||||
pulls.compare_base=base
|
||||
pulls.compare_base=Base
|
||||
pulls.compare_compare=vergleichen
|
||||
pulls.filter_branch=Filter Branch
|
||||
pulls.no_results=Keine Ergebnisse verfügbar.
|
||||
pulls.nothing_to_compare=Es ist nichts zu vergleichen, da Base- und Head-Branch gleich sind.
|
||||
pulls.has_pull_request=`Es existiert bereits eine Pull-Anforderung zwischen diesen beiden Zielen: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.create=Pull Request erstellen
|
||||
pulls.title_desc=wants to merge %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code>
|
||||
pulls.title_desc=möchte %[1]d Commits von <code>%[2]s</code> nach <code>%[3]s</code> zusammenführen
|
||||
pulls.merged_title_desc=%[1]d Commits von <code>%[2]s</code> nach <code>%[3]s</code> %[4]s zusammengeführt
|
||||
pulls.tab_conversation=Unterhaltung
|
||||
pulls.tab_commits=Commits
|
||||
pulls.tab_files=Dateien geändert
|
||||
pulls.reopen_to_merge=Bitte diese Pull-Anforderung wiedereröffnen, um die Merge-Operation auszuführen.
|
||||
pulls.merged=Zusammengeführt
|
||||
pulls.has_merged=This pull request has been merged successfully!
|
||||
pulls.has_merged=Dieser Pull-Request wurde erfolgreich zusammengeführt!
|
||||
pulls.data_broken=Die Daten dieser Pull-Anforderung sind defekt aufgrund des Löschens von Fork-Informationen.
|
||||
pulls.can_auto_merge_desc=Du kannst eine Auto-Merge Operation auf diese Pull-Anforderung durchführen.
|
||||
pulls.cannot_auto_merge_desc=Es kann keine Auto-Merge Operation durchgeführt werden, da es Konflikte zwischen den Commits gibt.
|
||||
pulls.cannot_auto_merge_helper=Bitte benutze ein Kommandozeilentool, um den Konflikt zu lösen.
|
||||
pulls.merge_pull_request=Merge Pull Request
|
||||
pulls.merge_pull_request=Pull-Request zusammenführen
|
||||
|
||||
milestones.new=Neuer Meilenstein
|
||||
milestones.open_tab=%d offen
|
||||
|
@ -924,7 +924,7 @@ commit_repo=hat nach <a href="%s/src/%s">%[2]s</a> in <a href="%[1]s">%[3]s</a>
|
|||
create_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> eröffnet`
|
||||
create_pull_request=`Pull-Anforderung erstellt <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> kommentiert`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> zuammengeführt`
|
||||
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="%s">%s</a>
|
||||
push_tag=hat nach <a href="%s/src/%s">%[2]s</a> in <a href="%[1]s">%[3]s</a> gepusht
|
||||
compare_2_commits=Zeige Vergleich dieser 2 Commits
|
||||
|
|
|
@ -241,7 +241,7 @@ location = Location
|
|||
update_profile = Update Profile
|
||||
update_profile_success = Your profile has been updated successfully.
|
||||
change_username = Username Changed
|
||||
change_username_desc = You changed your username. This will affect the way how links relate to your account. Do you want to continue?
|
||||
change_username_prompt = This change will affect the way how links relate to your account.
|
||||
continue = Continue
|
||||
cancel = Cancel
|
||||
|
||||
|
@ -630,7 +630,6 @@ release.tag_name_already_exist = Release with this tag name has already existed.
|
|||
[org]
|
||||
org_name_holder = Organization Name
|
||||
org_name_helper = Great organization names are short and memorable.
|
||||
org_email_helper = Organization's E-mail receives all notifications and confirmations.
|
||||
create_org = Create Organization
|
||||
repo_updated = Updated
|
||||
people = People
|
||||
|
@ -655,9 +654,9 @@ settings.full_name = Full Name
|
|||
settings.website = Website
|
||||
settings.location = Location
|
||||
settings.update_settings = Update Settings
|
||||
settings.change_orgname = Organization Name Changed
|
||||
settings.change_orgname_desc = Organization name has been changed. This will affect how links relate to the organization. Do you want to continue?
|
||||
settings.update_setting_success = Organization settings were successfully updated.
|
||||
settings.update_setting_success = Organization settings has been updated successfully.
|
||||
settings.change_orgname_prompt = This change will affect how links relate to the organization.
|
||||
settings.update_avatar_success = Organization avatar setting has been updated successfully.
|
||||
settings.delete = Delete Organization
|
||||
settings.delete_account = Delete This Organization
|
||||
settings.delete_prompt = The organization will be permanently removed, and this <strong>CANNOT</strong> be undone!
|
||||
|
@ -774,9 +773,9 @@ users.admin = Admin
|
|||
users.repos = Repos
|
||||
users.created = Created
|
||||
users.edit = Edit
|
||||
users.auth_source = Authorization Source
|
||||
users.auth_source = Authentication Source
|
||||
users.local = Local
|
||||
users.auth_login_name = Authorization Login Name
|
||||
users.auth_login_name = Authentication Login Name
|
||||
users.update_profile_success = Account profile has been updated successfully.
|
||||
users.edit_account = Edit Account
|
||||
users.is_activated = This account is activated
|
||||
|
@ -800,14 +799,14 @@ repos.watches = Watches
|
|||
repos.stars = Stars
|
||||
repos.issues = Issues
|
||||
|
||||
auths.auth_manage_panel = Authorization Manage Panel
|
||||
auths.new = Add New Authorization Source
|
||||
auths.auth_manage_panel = Authentication Manage Panel
|
||||
auths.new = Add New Authentication Source
|
||||
auths.name = Name
|
||||
auths.type = Type
|
||||
auths.enabled = Enabled
|
||||
auths.updated = Updated
|
||||
auths.auth_type = Authorization Type
|
||||
auths.auth_name = Authorization Name
|
||||
auths.auth_type = Authentication Type
|
||||
auths.auth_name = Authentication Name
|
||||
auths.domain = Domain
|
||||
auths.host = Host
|
||||
auths.port = Port
|
||||
|
@ -821,7 +820,7 @@ auths.attribute_mail = E-mail attribute
|
|||
auths.filter = User Filter
|
||||
auths.admin_filter = Admin Filter
|
||||
auths.ms_ad_sa = Ms Ad SA
|
||||
auths.smtp_auth = SMTP Authorization Type
|
||||
auths.smtp_auth = SMTP Authentication Type
|
||||
auths.smtphost = SMTP Host
|
||||
auths.smtpport = SMTP Port
|
||||
auths.enable_tls = Enable TLS Encryption
|
||||
|
@ -829,13 +828,13 @@ auths.skip_tls_verify = Skip TLS Verify
|
|||
auths.pam_service_name = PAM Service Name
|
||||
auths.enable_auto_register = Enable Auto Registration
|
||||
auths.tips = Tips
|
||||
auths.edit = Edit Authorization Setting
|
||||
auths.edit = Edit Authentication Setting
|
||||
auths.activated = This authentication has activated
|
||||
auths.update_success = Authorization setting has been updated successfully.
|
||||
auths.update = Update Authorization Setting
|
||||
auths.delete = Delete This Authorization
|
||||
auths.delete_auth_title = Authorization Deletion
|
||||
auths.delete_auth_desc = This authorization is going to be deleted, do you want to continue?
|
||||
auths.update_success = Authentication setting has been updated successfully.
|
||||
auths.update = Update Authentication Setting
|
||||
auths.delete = Delete This Authentication
|
||||
auths.delete_auth_title = Authentication Deletion
|
||||
auths.delete_auth_desc = This authentication is going to be deleted, do you want to continue?
|
||||
|
||||
config.server_config = Server Configuration
|
||||
config.app_name = Application Name
|
||||
|
|
|
@ -76,8 +76,8 @@ run_user=Abrir el usuario
|
|||
run_user_helper=El usuario necesita tener acceso a la Ruta Raíz del Repositorio y ejecutar Gogs.
|
||||
domain=Dominio
|
||||
domain_helper=Esto afecta a las URLs para clonar por SSH.
|
||||
ssh_port=SSH Port
|
||||
ssh_port_helper=Port number which your SSH server is using, leave it empty to disable SSH feature.
|
||||
ssh_port=Puerto SSH
|
||||
ssh_port_helper=Número de puerto de su servidor SSH, déjelo en blanco para desactivar SSH.
|
||||
http_port=Puerto HTTP
|
||||
http_port_helper=Puerto en el que escuchará la aplicación.
|
||||
app_url=URL de la aplicación
|
||||
|
@ -95,8 +95,8 @@ mail_notify=Habilitar las Notificaciones de Correo
|
|||
server_service_title=Configuración de Servidor y Otros Servicios
|
||||
offline_mode=Activar el modo Sin Conexión
|
||||
offline_mode_popup=Desactivar el CDN incluso en el modo de producción, todos los recursos se servirán localmente.
|
||||
disable_gravatar=Disable Gravatar Service
|
||||
disable_gravatar_popup=Disable Gravatar and custom sources, all avatars are uploaded by users or default.
|
||||
disable_gravatar=Desactivar el Servicio Gravatar
|
||||
disable_gravatar_popup=Desactivar Gravatar y cualquier fuente personalizada, todos los avatares deben ser cargados por los usuarios o el avatar por defecto.
|
||||
disable_registration=Desactivar Auto-Registro
|
||||
disable_registration_popup=Desactivar auto-registro del usuario, solo el administrador podrá crear cuentas nuevas.
|
||||
require_sign_in_view=Activar el Inicio de Sesión obligatorio para Ver Páginas
|
||||
|
@ -125,9 +125,9 @@ my_repos=Mis Repositorios
|
|||
collaborative_repos=Repositorios Colaborativos
|
||||
my_orgs=Mis Organizaciones
|
||||
my_mirrors=Mis Mirrors
|
||||
view_home=View %s
|
||||
view_home=Ver %s
|
||||
|
||||
issues.in_your_repos=In your repositories
|
||||
issues.in_your_repos=En sus repositorios
|
||||
|
||||
[explore]
|
||||
repos=Repositorios
|
||||
|
@ -281,14 +281,14 @@ key_name=Nombre de la Clave
|
|||
key_content=Contenido
|
||||
add_key_success=¡Nueva clave SSH '%s' añadida correctamente!
|
||||
delete_key=Eliminar
|
||||
ssh_key_deletion=SSH Key Deletion
|
||||
ssh_key_deletion_desc=Delete this SSH key will remove all related accesses for your account. Do you want to continue?
|
||||
ssh_key_deletion_success=SSH key has been deleted successfully!
|
||||
ssh_key_deletion=Borrado de Llave SSH
|
||||
ssh_key_deletion_desc=Al borrar esta llave SSH no podrá volver a acceder con ella a su cuenta. Desea continuar?
|
||||
ssh_key_deletion_success=¡La llave SSH ha sido eliminada con éxito!
|
||||
add_on=Añadido en
|
||||
last_used=Utilizado por última vez en
|
||||
no_activity=No hay actividad reciente
|
||||
key_state_desc=Esta clave ha sido usada en los últimos 7 días
|
||||
token_state_desc=This token is used in last 7 days
|
||||
token_state_desc=Este token ha sido usado en los últimos 7 días
|
||||
|
||||
manage_social=Gestionar Redes Sociales asociadas
|
||||
social_desc=Esta es una lista de las Redes Sociales asociadas. Elimina cualquier vínculo que no reconozcas.
|
||||
|
@ -297,15 +297,15 @@ unbind_success=La Red Social ha sido desvinculada.
|
|||
|
||||
manage_access_token=Gestionar los Tokens de Acceso personales
|
||||
generate_new_token=Generar nuevo Token
|
||||
tokens_desc=Tokens you have generated that can be used to access the Gogs APIs.
|
||||
tokens_desc=Tokens generados que se pueden usar para acceder al API de Gogs.
|
||||
new_token_desc=Desde ahora, todos los tokens tendrán acceso completo a tu cuenta.
|
||||
token_name=Nombre del Token
|
||||
generate_token=Generar Token
|
||||
generate_token_succees=¡Los nuevos tokens de acceso se han generado correctamente! Asegúrate de copiar tu nuevo token de acceso personal. ¡No podrás verlo de nuevo!
|
||||
delete_token=Eliminar
|
||||
access_token_deletion=Personal Access Token Deletion
|
||||
access_token_deletion_desc=Delete this personal access token will remove all related accesses of application. Do you want to continue?
|
||||
delete_token_success=Personal access token has been removed successfully! Don't forget to update your application as well.
|
||||
access_token_deletion=Borrado de Token de Acceso Personal
|
||||
access_token_deletion_desc=Si elimina este token de acceso personal la aplicación asociada perderá el permiso de acceso. ¿Desea continuar?
|
||||
delete_token_success=¡El token de acceso personal ha sido eliminado con éxito! No se olvide de actualizar también las aplicaciones asociadas.
|
||||
|
||||
delete_account=Elimina tu cuenta
|
||||
delete_prompt=La operación eliminará tu cuenta de forma permanente y ¡<strong>NO</strong> se puede deshacer!
|
||||
|
@ -319,18 +319,18 @@ repo_name=Nombre del Repositorio
|
|||
repo_name_helper=Los grandes nombres de repositorios son cortos, memorables y <strong>únicos</strong>.
|
||||
visibility=Visibilidad
|
||||
visiblity_helper=Este repositorio es <span class="ui red text">Privado</span>
|
||||
visiblity_fork_helper=(Change of this value will affect all forks)
|
||||
visiblity_fork_helper=(Este cambio afectará a todos los forks)
|
||||
fork_repo=Hacer Fork del repositorio
|
||||
fork_from=Crear un Fork desde
|
||||
fork_visiblity_helper=No es posible cambiar la visibilidad de un Fork
|
||||
repo_desc=Descripción
|
||||
repo_lang=Idioma
|
||||
repo_lang_helper=Select .gitignore files
|
||||
repo_lang_helper=Seleccione archivo .gitignore
|
||||
license=Licencia
|
||||
license_helper=Selecciona un fichero de licencia
|
||||
readme=Readme
|
||||
readme_helper=Select a readme template
|
||||
auto_init=Initialize this repository selected files and template
|
||||
readme_helper=Seleccione una plantilla de archivo readme
|
||||
auto_init=Inicializar los archivos seleccionados y plantillas de este repositorio
|
||||
create_repo=Crear Repositorio
|
||||
default_branch=Rama por defecto
|
||||
mirror_interval=Intervalo de mirror(en horas)
|
||||
|
@ -340,10 +340,10 @@ form.name_pattern_not_allowed=El patrón del nombre del repositorio '%s' no est
|
|||
|
||||
need_auth=Requiere Autorización
|
||||
migrate_type=Tipo de Migración
|
||||
migrate_type_helper=This repository will be a <span class="text blue">mirror</span>
|
||||
migrate_type_helper=Este repositorio será un <span class="text blue">mirror</span>
|
||||
migrate_repo=Migrar Repositorio
|
||||
migrate.clone_address=Clonar Dirección
|
||||
migrate.clone_address_desc=This can be a HTTP/HTTPS/GIT URL or local server path.
|
||||
migrate.clone_address_desc=Esto puede ser una URL HTTP/HTTPS/GIT o una ruta local del servidor.
|
||||
migrate.invalid_local_path=Rutal local inválida, no existe o no es un directorio.
|
||||
|
||||
forked_from=forked de
|
||||
|
@ -410,46 +410,46 @@ issues.close_tab=%d cerradas
|
|||
issues.filter_label=Etiqueta
|
||||
issues.filter_label_no_select=Ninguna etiqueta seleccionada
|
||||
issues.filter_milestone=Milestone
|
||||
issues.filter_milestone_no_select=No selected milestone
|
||||
issues.filter_milestone_no_select=Milestone no seleccionado
|
||||
issues.filter_assignee=Asignada por
|
||||
issues.filter_assginee_no_select=No selected Assignee
|
||||
issues.filter_assginee_no_select=Sin asignar
|
||||
issues.filter_type=Tipo
|
||||
issues.filter_type.all_issues=Todas las incidencias
|
||||
issues.filter_type.assigned_to_you=Asignada a ti
|
||||
issues.filter_type.created_by_you=Creada por ti
|
||||
issues.filter_type.mentioning_you=Citado en
|
||||
issues.filter_sort=Sort
|
||||
issues.filter_sort.latest=Newest
|
||||
issues.filter_sort.oldest=Oldest
|
||||
issues.filter_sort.recentupdate=Recently updated
|
||||
issues.filter_sort=Ordenar
|
||||
issues.filter_sort.latest=Más recientes
|
||||
issues.filter_sort.oldest=Más antiguos
|
||||
issues.filter_sort.recentupdate=Actualizada recientemente
|
||||
issues.filter_sort.leastupdate=Least recently updated
|
||||
issues.filter_sort.mostcomment=Most commented
|
||||
issues.filter_sort.leastcomment=Least commented
|
||||
issues.opened_by=opened %[1]s by <a href="%[2]s">%[3]s</a>
|
||||
issues.opened_by_fake=opened %[1]s by %[2]s
|
||||
issues.filter_sort.mostcomment=Más comentadas
|
||||
issues.filter_sort.leastcomment=Menos comentadas
|
||||
issues.opened_by=abierta %[1]s por <a href="%[2]s">%[3]s</a>
|
||||
issues.opened_by_fake=abierta %[1]s por %[2]s
|
||||
issues.previous=Página Anterior
|
||||
issues.next=Página Siguiente
|
||||
issues.open_title=Open
|
||||
issues.closed_title=Closed
|
||||
issues.num_comments=%d comments
|
||||
issues.commented_at=`commented <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.no_content=There is no content yet.
|
||||
issues.close_issue=Close
|
||||
issues.close_comment_issue=Close and comment
|
||||
issues.reopen_issue=Reopen
|
||||
issues.reopen_comment_issue=Reopen and comment
|
||||
issues.create_comment=Comment
|
||||
issues.closed_at=`closed <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reopened <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`referenced this issue from a commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.open_title=Abierta
|
||||
issues.closed_title=Cerrada
|
||||
issues.num_comments=%d comentarios
|
||||
issues.commented_at=`comentada <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.no_content=No hay contenido por el momento.
|
||||
issues.close_issue=Cerrar
|
||||
issues.close_comment_issue=Cerrar y Comentar
|
||||
issues.reopen_issue=Reabrir
|
||||
issues.reopen_comment_issue=Reabrir y Comentar
|
||||
issues.create_comment=Comentar
|
||||
issues.closed_at=`cerrada <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`reabierta <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`mencionada esta incidencia en un commit <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.poster=Poster
|
||||
issues.admin=Admin
|
||||
issues.owner=Owner
|
||||
issues.sign_up_for_free=Sign up for free
|
||||
issues.sign_in_require_desc=to join this conversation. Already have an account? <a href="%s">Sign in to comment</a>
|
||||
issues.edit=Edit
|
||||
issues.cancel=Cancel
|
||||
issues.save=Save
|
||||
issues.admin=Administrador
|
||||
issues.owner=Propietario
|
||||
issues.sign_up_for_free=Registro gratuito
|
||||
issues.sign_in_require_desc=para unirse a esta conversación. Ya dispone de una cuenta? <a href="%s">Inicie sesión para comentar</a>
|
||||
issues.edit=Editar
|
||||
issues.cancel=Cancelar
|
||||
issues.save=Guardar
|
||||
issues.label_title=Nombre etiqueta
|
||||
issues.label_color=Color etiqueta
|
||||
issues.label_count=%d etiquetas
|
||||
|
@ -461,52 +461,52 @@ issues.label_deletion=Borrado de Etiqueta
|
|||
issues.label_deletion_desc=Al borrar la etiqueta su información será eliminada de todas las incidencias relacionadas. Desea continuar?
|
||||
issues.label_deletion_success=Etiqueta borrada con éxito!
|
||||
|
||||
pulls.compare_changes=Compare Changes
|
||||
pulls.compare_changes_desc=Compare two branches and make a pull request for changes.
|
||||
pulls.compare_changes=Comparar Cambios
|
||||
pulls.compare_changes_desc=Comparar dos ramas y generar un pull request con las diferencias.
|
||||
pulls.compare_base=base
|
||||
pulls.compare_compare=compare
|
||||
pulls.filter_branch=Filter branch
|
||||
pulls.no_results=No results found.
|
||||
pulls.nothing_to_compare=There is nothing to compare because base and head branches are even.
|
||||
pulls.has_pull_request=`There is already a pull request between these two targets: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.create=Create Pull Request
|
||||
pulls.title_desc=wants to merge %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code>
|
||||
pulls.merged_title_desc=merged %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code> %[4]s
|
||||
pulls.tab_conversation=Conversation
|
||||
pulls.compare_compare=comparar con
|
||||
pulls.filter_branch=Filtrar rama
|
||||
pulls.no_results=No se han encontrado resultados.
|
||||
pulls.nothing_to_compare=No hay nada que comparar porque las dos ramas coinciden.
|
||||
pulls.has_pull_request=`Ya existe un pull request entre estas dos ramas: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.create=Nuevo Pull Request
|
||||
pulls.title_desc=desea fusionar %[1]d commits de <code>%[2]s</code> en <code>%[3]s</code>
|
||||
pulls.merged_title_desc=fusionados %[1]d commits de <code>%[2]s</code> en <code>%[3]s</code> %[4]s
|
||||
pulls.tab_conversation=Conversación
|
||||
pulls.tab_commits=Commits
|
||||
pulls.tab_files=Files changed
|
||||
pulls.reopen_to_merge=Please reopen this pull request to perform merge operation.
|
||||
pulls.merged=Merged
|
||||
pulls.has_merged=This pull request has been merged successfully!
|
||||
pulls.data_broken=Data of this pull request has been broken due to deletion of fork information.
|
||||
pulls.can_auto_merge_desc=You can perform auto-merge operation on this pull request.
|
||||
pulls.cannot_auto_merge_desc=You can't perform auto-merge operation because there are conflicts between commits.
|
||||
pulls.cannot_auto_merge_helper=Please use command line tool to solve it.
|
||||
pulls.merge_pull_request=Merge Pull Request
|
||||
pulls.tab_files=Archivos modificados
|
||||
pulls.reopen_to_merge=Por favor reabra este pull request para proceder con la operación de fusionado.
|
||||
pulls.merged=Fuisionado
|
||||
pulls.has_merged=¡Este pull request se ha completado con éxito!
|
||||
pulls.data_broken=Los datos de este pull request ya no están disponibles porque se ha eliminado la información del fork.
|
||||
pulls.can_auto_merge_desc=Puede realizar la operación auto-fusionado en este pull request.
|
||||
pulls.cannot_auto_merge_desc=No puede realizar la operación de auto-fusionado porque existen conflictos entre los commits.
|
||||
pulls.cannot_auto_merge_helper=Por favor use la línea de comandos para resolverlo.
|
||||
pulls.merge_pull_request=Fusionar Pull Request
|
||||
|
||||
milestones.new=New Milestone
|
||||
milestones.open_tab=%d Open
|
||||
milestones.close_tab=%d Closed
|
||||
milestones.closed=Closed %s
|
||||
milestones.no_due_date=No due date
|
||||
milestones.open=Open
|
||||
milestones.close=Close
|
||||
milestones.new_subheader=Create milestones to organize your issues.
|
||||
milestones.create=Create Milestone
|
||||
milestones.title=Title
|
||||
milestones.desc=Description
|
||||
milestones.due_date=Due Date (optional)
|
||||
milestones.clear=Clear
|
||||
milestones.invalid_due_date_format=Due date format is invalid, must be 'year-mm-dd'.
|
||||
milestones.create_success=Milestone '%s' has been created successfully!
|
||||
milestones.edit=Edit Milestone
|
||||
milestones.edit_subheader=Use better description for milestones so people won't be confused.
|
||||
milestones.cancel=Cancel
|
||||
milestones.modify=Modify Milestone
|
||||
milestones.edit_success=Changes of milestone '%s' has been saved successfully!
|
||||
milestones.deletion=Milestone Deletion
|
||||
milestones.deletion_desc=Delete this milestone will remove its information in all related issues. Do you want to continue?
|
||||
milestones.deletion_success=Milestone has been deleted successfully!
|
||||
milestones.new=Nuevo Milestone
|
||||
milestones.open_tab=%d abiertas
|
||||
milestones.close_tab=%d cerradas
|
||||
milestones.closed=Cerrada %s
|
||||
milestones.no_due_date=Sin fecha límite
|
||||
milestones.open=Abrir
|
||||
milestones.close=Cerrada
|
||||
milestones.new_subheader=Cree milestones para organizar las incidencias.
|
||||
milestones.create=Nuevo Milestone
|
||||
milestones.title=Título
|
||||
milestones.desc=Descripción
|
||||
milestones.due_date=Fecha límite (opcional)
|
||||
milestones.clear=Eliminar
|
||||
milestones.invalid_due_date_format=El formato de la fecha límite no es válido, debe ser 'y-mm-dd'.
|
||||
milestones.create_success=¡El milestone '%s' ha sido creado con éxito!
|
||||
milestones.edit=Editar Milestone
|
||||
milestones.edit_subheader=Use una buena descripción en el milestone para no confundir al resto de usuarios.
|
||||
milestones.cancel=Cancelar
|
||||
milestones.modify=Modificar Milestone
|
||||
milestones.edit_success=¡Los cambios al milestone '%s' se han guardado con éxito!
|
||||
milestones.deletion=Borrar milestone
|
||||
milestones.deletion_desc=El borrado de este milestone eliminará su información y las incidencias asociadas. ¿Desea continuar?
|
||||
milestones.deletion_success=¡El milestone ha sido eliminado con éxito!
|
||||
|
||||
settings=Configuración
|
||||
settings.options=Opciones
|
||||
|
@ -523,14 +523,14 @@ settings.transfer_desc=Transferir este repositorio a otro usuario u organizació
|
|||
settings.new_owner_has_same_repo=El nuevo propietario tiene un repositorio con el mismo nombre.
|
||||
settings.delete=Eliminar este Repositorio
|
||||
settings.delete_desc=Una vez has eliminado un repositorio, no hay vuelta atrás. Por favor, asegúrate de que es lo que quieres.
|
||||
settings.transfer_notices_1=- You will lose access if new owner is a individual user.
|
||||
settings.transfer_notices_2=- You will conserve access if new owner is an organization and if you're one of the owners.
|
||||
settings.transfer_form_title=Please enter following information to confirm your operation:
|
||||
settings.delete_notices_1=- This operation <strong>CANNOT</strong> be undone.
|
||||
settings.delete_notices_2=- This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
|
||||
settings.delete_notices_fork_1=- If this repository is public, all forks will be became independent after deletion.
|
||||
settings.delete_notices_fork_2=- If this repository is private, all forks will be removed at the same time.
|
||||
settings.delete_notices_fork_3=- If you want to keep all forks after deletion, please change visibility of this repository to public first.
|
||||
settings.transfer_notices_1=- Perderá el permiso de acceso si el nuevo propietario es otro usuario.
|
||||
settings.transfer_notices_2=- Conservará el privilegio de acceso si el nuevo propietario es una organización y usted es uno de los propietarios de dicha organización.
|
||||
settings.transfer_form_title=Por favor introduzca esta información para confirmar la operación:
|
||||
settings.delete_notices_1=- Esta operación <strong>NO PUEDE</strong> revertirse.
|
||||
settings.delete_notices_2=- Esta operación eliminará de manera permanente todo el contenido de este repositorio, incluyendo los datos de git, las incidencias, los comentarios y los permisos de acceso de los colaboradores.
|
||||
settings.delete_notices_fork_1=- Si este repositorio es público, todos los forks se convertirán en repositorios independientes tras el borrado.
|
||||
settings.delete_notices_fork_2=- Si este repositorio es privado, todos los forks serán eliminados simultáneamente.
|
||||
settings.delete_notices_fork_3=- Si desea mantener los forks tras el borrado, por favor convierta este repositorio en público antes de proceder.
|
||||
settings.update_settings_success=Las opciones del repositorio se han actualizado correctamente.
|
||||
settings.transfer_owner=Nuevo Propietario
|
||||
settings.make_transfer=Transferir
|
||||
|
@ -542,14 +542,14 @@ settings.remove_collaborator_success=Se ha eliminado el colaborador.
|
|||
settings.user_is_org_member=El usuario es miembro de la organización, no puede ser añadido como colaborador.
|
||||
settings.add_webhook=Añadir Webhook
|
||||
settings.hooks_desc=Los Webhooks permiten a servicios externos recibir notificaciones cuando sucedan ciertos eventos en Gogs. Cuando sucedan los eventos especificados, enviaremos una petición POST a cada una de las URLs indicadas. Para obtener más información, consulta nuestra <a target="_blank" href="%s">Guía de Webhooks</a>.
|
||||
settings.webhook_deletion=Delete Webhook
|
||||
settings.webhook_deletion_desc=Delete this webhook will remove its information and all delivery history. Do you want to continue?
|
||||
settings.webhook_deletion_success=Webhook has been deleted successfully!
|
||||
settings.webhook.request=Request
|
||||
settings.webhook.response=Response
|
||||
settings.webhook.headers=Headers
|
||||
settings.webhook_deletion=Eliminar Webhook
|
||||
settings.webhook_deletion_desc=El borrado de este webhook eliminará su información y todo su historial. ¿Desea continuar?
|
||||
settings.webhook_deletion_success=¡Webhook eliminado con éxito!
|
||||
settings.webhook.request=Petición
|
||||
settings.webhook.response=Respuesta
|
||||
settings.webhook.headers=Encabezado
|
||||
settings.webhook.payload=Payload
|
||||
settings.webhook.body=Body
|
||||
settings.webhook.body=Cuerpo del mensaje
|
||||
settings.githooks_desc=Los Git Hooks son una funcionalidad del propio Git, puedes editar los ficheros de los hooks soportados en la siguiente lista para aplicar operaciones personalizadas.
|
||||
settings.githook_edit_desc=Si el hook no está activo, se mostrará contenido de ejemplo. Dejar el contenido vacío deshabilitará este hook.
|
||||
settings.githook_name=Nombre del Hook
|
||||
|
@ -559,17 +559,17 @@ settings.add_webhook_desc=Enviaremos una petición <code>POST</code> a la siguie
|
|||
settings.payload_url=URL de Payload
|
||||
settings.content_type=Tipo de Contenido
|
||||
settings.secret=Secreto
|
||||
settings.slack_username=Username
|
||||
settings.slack_icon_url=Icon URL
|
||||
settings.slack_username=Nombre de usuario
|
||||
settings.slack_icon_url=URL de icono
|
||||
settings.slack_color=Color
|
||||
settings.event_desc=¿Qué eventos te gustaría que desencadenasen este webhook?
|
||||
settings.event_push_only=Solo el evento <code>push</code>.
|
||||
settings.event_send_everything=I need <strong>everything</strong>.
|
||||
settings.event_choose=Let me choose what I need.
|
||||
settings.event_create=Create
|
||||
settings.event_create_desc=Branch, or tag created
|
||||
settings.event_send_everything=Necesito <strong>todo</strong>.
|
||||
settings.event_choose=Déjeme elegir lo que necesito.
|
||||
settings.event_create=Crear
|
||||
settings.event_create_desc=Branch o etiqueta creada
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push to a repository
|
||||
settings.event_push_desc=Git push a un repositorio
|
||||
settings.active=Activo
|
||||
settings.active_helper=Enviaremos detalles del evento cuando este hook se dispare.
|
||||
settings.add_hook_success=Se ha añadido un nuevo webhook.
|
||||
|
@ -585,8 +585,8 @@ settings.slack_channel=Canal
|
|||
settings.deploy_keys=Claves de Despliegue
|
||||
settings.add_deploy_key=Add Deploy Key
|
||||
settings.no_deploy_keys=You haven't added any deploy key.
|
||||
settings.title=Title
|
||||
settings.deploy_key_content=Content
|
||||
settings.title=Título
|
||||
settings.deploy_key_content=Contenido
|
||||
settings.key_been_used=Deploy key content has been used.
|
||||
settings.key_name_used=Deploy key with same name has already existed.
|
||||
settings.add_key_success=New deploy key '%s' has been added successfully!
|
||||
|
@ -824,7 +824,7 @@ auths.smtp_auth=Tipo de Autorización SMTP
|
|||
auths.smtphost=SMTP Host
|
||||
auths.smtpport=Puerto SMTP
|
||||
auths.enable_tls=Habilitar Cifrado TLS
|
||||
auths.skip_tls_verify=Skip TLS Verify
|
||||
auths.skip_tls_verify=Omitir la verificación TLS
|
||||
auths.pam_service_name=Nombre del Servicio PAM
|
||||
auths.enable_auto_register=Hablilitar Auto-Registro
|
||||
auths.tips=Consejos
|
||||
|
@ -869,7 +869,7 @@ config.enable_cache_avatar=Activar la Caché de Avatar
|
|||
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.queue_length=Queue Length
|
||||
config.queue_length=Tamaño de Cola de Envío
|
||||
config.deliver_timeout=Timeout de Entrega
|
||||
config.skip_tls_verify=Omitir la Verificación TLS
|
||||
config.mailer_config=Configuración del Mailer
|
||||
|
@ -919,12 +919,12 @@ notices.delete_success=La notificación del sistema se ha eliminado correctament
|
|||
|
||||
[action]
|
||||
create_repo=Repositorio creado <a href="%s">%s</a>
|
||||
rename_repo=renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a>
|
||||
rename_repo=repositorio renombrado de <code>%[1]s</code> a <a href="%[2]s">%[3]s</a>
|
||||
commit_repo=hizo push a <a href="%s/src/%s">%[2]s</a> en <a href="%[1]s">%[3]s</a>
|
||||
create_issue=`incidencia abierta <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
create_pull_request=`creado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue=`comentó en la incidencia <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
merge_pull_request=`fusionado pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo=transfirió el repositorio <code>%s</code> a <a href="%s">%s</a>
|
||||
push_tag=hizo push del tag <a href="%s/src/%s">%[2]s</a> a <a href="%[1]s">%[3]s</a>
|
||||
compare_2_commits=Ver la comparación de estos 2 commits
|
||||
|
@ -951,8 +951,8 @@ raw_seconds=segundos
|
|||
raw_minutes=minutos
|
||||
|
||||
[dropzone]
|
||||
default_message=Drop files here or click to upload.
|
||||
invalid_input_type=You can't upload files of this type.
|
||||
file_too_big=File size({{filesize}} MB) exceeds maximum size({{maxFilesize}} MB).
|
||||
remove_file=Remove file
|
||||
default_message=Suéltelos aquí o pulse para cargar archivos.
|
||||
invalid_input_type=No está permitido cargar archivos de este tipo.
|
||||
file_too_big=El tamaño del archivo ({{filesize}} MB) excede el tamaño máximo ({{maxFilesize}} MB).
|
||||
remove_file=Eliminar archivo
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ repo_lang=Idioma
|
|||
repo_lang_helper=Selecione arquivos .gitignore
|
||||
license=Licença
|
||||
license_helper=Selecione um arquivo de licença
|
||||
readme=Readme
|
||||
readme=Leia-me
|
||||
readme_helper=Select a readme template
|
||||
auto_init=Initialize this repository selected files and template
|
||||
create_repo=Criar Repositório
|
||||
|
@ -464,7 +464,7 @@ issues.label_deletion_success=A etiqueta foi excluída com sucesso!
|
|||
pulls.compare_changes=Comparar mudanças
|
||||
pulls.compare_changes_desc=Comparar dois ramos e criar solicitação de pull com as mudanças.
|
||||
pulls.compare_base=base
|
||||
pulls.compare_compare=compare
|
||||
pulls.compare_compare=comparar
|
||||
pulls.filter_branch=Filter branch
|
||||
pulls.no_results=Nada encontrado.
|
||||
pulls.nothing_to_compare=There is nothing to compare because base and head branches are even.
|
||||
|
|
|
@ -95,8 +95,8 @@ mail_notify=啟用郵件通知提醒
|
|||
server_service_title=伺服器和其他服務設置
|
||||
offline_mode=啓用離線模式
|
||||
offline_mode_popup=在部署模式下也禁用從 CDN 獲取文件,所有的資源將從本地伺服器獲取。
|
||||
disable_gravatar=Disable Gravatar Service
|
||||
disable_gravatar_popup=Disable Gravatar and custom sources, all avatars are uploaded by users or default.
|
||||
disable_gravatar=禁用 Gravatar 服務
|
||||
disable_gravatar_popup=禁用 Gravatar 和自定義源,僅使用由用戶上傳或默認的頭像。
|
||||
disable_registration=禁止用戶自主註冊
|
||||
disable_registration_popup=禁止用戶自主註冊功能,只有管理員可以添加帳號。
|
||||
require_sign_in_view=啓用登錄訪問限制
|
||||
|
@ -125,9 +125,9 @@ my_repos=我的倉庫
|
|||
collaborative_repos=參與協作的倉庫
|
||||
my_orgs=我的組織
|
||||
my_mirrors=我的鏡像
|
||||
view_home=View %s
|
||||
view_home=訪問 %s
|
||||
|
||||
issues.in_your_repos=In your repositories
|
||||
issues.in_your_repos=屬於該用戶倉庫的
|
||||
|
||||
[explore]
|
||||
repos=探索倉庫
|
||||
|
@ -281,9 +281,9 @@ key_name=密鑰名稱
|
|||
key_content=密鑰內容
|
||||
add_key_success=新的 SSH 密鑰 '%s' 添加成功!
|
||||
delete_key=刪除
|
||||
ssh_key_deletion=SSH Key Deletion
|
||||
ssh_key_deletion_desc=Delete this SSH key will remove all related accesses for your account. Do you want to continue?
|
||||
ssh_key_deletion_success=SSH key has been deleted successfully!
|
||||
ssh_key_deletion=刪除 SSH 公鑰
|
||||
ssh_key_deletion_desc=刪除該 SSH 公鑰將刪除所有與您帳戶相關的訪問權限。是否繼續?
|
||||
ssh_key_deletion_success=SSH 公鑰刪除成功!
|
||||
add_on=增加於
|
||||
last_used=上次使用在
|
||||
no_activity=沒有最近活動
|
||||
|
@ -319,7 +319,7 @@ repo_name=倉庫名稱
|
|||
repo_name_helper=偉大的倉庫名稱一般都較短、令人深刻並且 <strong>獨一無二</strong> 的。
|
||||
visibility=可見度
|
||||
visiblity_helper=該倉庫為 <span class="ui red text">私有的</span>
|
||||
visiblity_fork_helper=(Change of this value will affect all forks)
|
||||
visiblity_fork_helper=(修改該值將會影響到所有派生倉庫)
|
||||
fork_repo=派生倉庫
|
||||
fork_from=派生自
|
||||
fork_visiblity_helper=派生倉庫無法修改可見性。
|
||||
|
|
|
@ -21,10 +21,6 @@ fi
|
|||
|
||||
service ssh start
|
||||
|
||||
# sync templates
|
||||
test -d /data/gogs/templates || cp -ar ./templates /data/gogs/
|
||||
rsync -rtv /data/gogs/templates/ ./templates/
|
||||
|
||||
ln -sf /data/gogs/log ./log
|
||||
ln -sf /data/gogs/data ./data
|
||||
ln -sf /data/git /home/git
|
||||
|
|
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.6.9.0903 Beta"
|
||||
const APP_VER = "0.6.9.0909 Beta"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
|
|
@ -758,7 +758,7 @@ func GetUserIssueStats(repoID, uid int64, repoIDs []int64, filterMode int, isPul
|
|||
|
||||
queryStr := "SELECT COUNT(*) FROM `issue` "
|
||||
baseCond := " WHERE issue.is_closed=?"
|
||||
if repoID > 0 {
|
||||
if repoID > 0 || len(repoIDs) == 0 {
|
||||
baseCond += " AND issue.repo_id=" + com.ToStr(repoID)
|
||||
} else {
|
||||
baseCond += " AND issue.repo_id IN (" + strings.Join(base.Int64sToStrings(repoIDs), ",") + ")"
|
||||
|
|
|
@ -72,6 +72,7 @@ var (
|
|||
}
|
||||
|
||||
EnableSQLite3 bool
|
||||
EnableTidb bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -143,6 +144,14 @@ func getEngine() (*xorm.Engine, error) {
|
|||
return nil, fmt.Errorf("Fail to create directories: %v", err)
|
||||
}
|
||||
cnnstr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc"
|
||||
case "tidb":
|
||||
if !EnableTidb {
|
||||
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
|
||||
}
|
||||
if err := os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm); err != nil {
|
||||
return nil, fmt.Errorf("Fail to create directories: %v", err)
|
||||
}
|
||||
cnnstr = "goleveldb://" + DbCfg.Path
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// +build tidb go1.4.2
|
||||
|
||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-xorm/tidb"
|
||||
_ "github.com/pingcap/tidb"
|
||||
)
|
||||
|
||||
func init() {
|
||||
EnableTidb = true
|
||||
}
|
|
@ -10,7 +10,7 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/go-xorm/xorm"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -93,17 +93,6 @@ func (org *User) RemoveOrgRepo(repoID int64) error {
|
|||
return org.removeOrgRepo(x, repoID)
|
||||
}
|
||||
|
||||
// IsOrgEmailUsed returns true if the e-mail has been used in organization account.
|
||||
func IsOrgEmailUsed(email string) (bool, error) {
|
||||
if len(email) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
return x.Get(&User{
|
||||
Email: email,
|
||||
Type: ORGANIZATION,
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOrganization creates record of a new organization.
|
||||
func CreateOrganization(org, owner *User) (err error) {
|
||||
if err = IsUsableName(org.Name); err != nil {
|
||||
|
@ -117,18 +106,9 @@ func CreateOrganization(org, owner *User) (err error) {
|
|||
return ErrUserAlreadyExist{org.Name}
|
||||
}
|
||||
|
||||
isExist, err = IsOrgEmailUsed(org.Email)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return ErrEmailAlreadyUsed{org.Email}
|
||||
}
|
||||
|
||||
org.LowerName = strings.ToLower(org.Name)
|
||||
org.FullName = org.Name
|
||||
org.Avatar = base.EncodeMd5(org.Email)
|
||||
org.AvatarEmail = org.Email
|
||||
// No password for organization.
|
||||
org.UseCustomAvatar = true
|
||||
org.NumTeams = 1
|
||||
org.NumMembers = 1
|
||||
|
||||
|
@ -141,6 +121,17 @@ func CreateOrganization(org, owner *User) (err error) {
|
|||
if _, err = sess.Insert(org); err != nil {
|
||||
return fmt.Errorf("insert organization: %v", err)
|
||||
}
|
||||
org.GenerateRandomAvatar()
|
||||
|
||||
// Add initial creator to organization and owner team.
|
||||
if _, err = sess.Insert(&OrgUser{
|
||||
Uid: owner.Id,
|
||||
OrgID: org.Id,
|
||||
IsOwner: true,
|
||||
NumTeams: 1,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("insert org-user relation: %v", err)
|
||||
}
|
||||
|
||||
// Create default owner team.
|
||||
t := &Team{
|
||||
|
@ -154,23 +145,11 @@ func CreateOrganization(org, owner *User) (err error) {
|
|||
return fmt.Errorf("insert owner team: %v", err)
|
||||
}
|
||||
|
||||
// Add initial creator to organization and owner team.
|
||||
ou := &OrgUser{
|
||||
Uid: owner.Id,
|
||||
OrgID: org.Id,
|
||||
IsOwner: true,
|
||||
NumTeams: 1,
|
||||
}
|
||||
if _, err = sess.Insert(ou); err != nil {
|
||||
return fmt.Errorf("insert org-user relation: %v", err)
|
||||
}
|
||||
|
||||
tu := &TeamUser{
|
||||
if _, err = sess.Insert(&TeamUser{
|
||||
Uid: owner.Id,
|
||||
OrgID: org.Id,
|
||||
TeamID: t.ID,
|
||||
}
|
||||
if _, err = sess.Insert(tu); err != nil {
|
||||
}); err != nil {
|
||||
return fmt.Errorf("insert team-user relation: %v", err)
|
||||
}
|
||||
|
||||
|
@ -212,7 +191,6 @@ func GetOrganizations(num, offset int) ([]*User, error) {
|
|||
return orgs, err
|
||||
}
|
||||
|
||||
// TODO: need some kind of mechanism to record failure.
|
||||
// DeleteOrganization completely and permanently deletes everything of organization.
|
||||
func DeleteOrganization(org *User) (err error) {
|
||||
if err := DeleteUser(org); err != nil {
|
||||
|
@ -220,23 +198,23 @@ func DeleteOrganization(org *User) (err error) {
|
|||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Delete(&Team{OrgID: org.Id}); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
if err = deleteBeans(sess,
|
||||
&Team{OrgID: org.Id},
|
||||
&OrgUser{OrgID: org.Id},
|
||||
&TeamUser{OrgID: org.Id},
|
||||
); err != nil {
|
||||
return fmt.Errorf("deleteBeans: %v", err)
|
||||
}
|
||||
if _, err = sess.Delete(&OrgUser{OrgID: org.Id}); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
if _, err = sess.Delete(&TeamUser{OrgID: org.Id}); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
|
||||
if err = deleteUser(sess, org); err != nil {
|
||||
return fmt.Errorf("deleteUser: %v", err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
|
@ -275,6 +253,25 @@ func IsPublicMembership(orgId, uid int64) bool {
|
|||
return has
|
||||
}
|
||||
|
||||
func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
|
||||
orgs := make([]*User, 0, 10)
|
||||
return orgs, sess.Where("`org_user`.uid=?", userID).And("`org_user`.is_owner=?", true).
|
||||
Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").Find(&orgs)
|
||||
}
|
||||
|
||||
// GetOwnedOrgsByUserID returns a list of organizations are owned by given user ID.
|
||||
func GetOwnedOrgsByUserID(userID int64) ([]*User, error) {
|
||||
sess := x.NewSession()
|
||||
return getOwnedOrgsByUserID(sess, userID)
|
||||
}
|
||||
|
||||
// GetOwnedOrganizationsByUserIDDesc returns a list of organizations are owned by
|
||||
// given user ID and descring order by given condition.
|
||||
func GetOwnedOrgsByUserIDDesc(userID int64, desc string) ([]*User, error) {
|
||||
sess := x.NewSession()
|
||||
return getOwnedOrgsByUserID(sess.Desc(desc), userID)
|
||||
}
|
||||
|
||||
// GetOrgUsersByUserId returns all organization-user relations by user ID.
|
||||
func GetOrgUsersByUserId(uid int64) ([]*OrgUser, error) {
|
||||
ous := make([]*OrgUser, 0, 10)
|
||||
|
|
|
@ -272,6 +272,11 @@ func (repo *Repository) IsOwnedBy(userID int64) bool {
|
|||
return repo.OwnerID == userID
|
||||
}
|
||||
|
||||
// CanBeForked returns true if repository meets the requirements of being forked.
|
||||
func (repo *Repository) CanBeForked() bool {
|
||||
return !repo.IsBare && !repo.IsMirror
|
||||
}
|
||||
|
||||
func (repo *Repository) NextIssueIndex() int64 {
|
||||
return int64(repo.NumIssues+repo.NumPulls) + 1
|
||||
}
|
||||
|
@ -465,6 +470,16 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
|
|||
return repo, fmt.Errorf("create update hook: %v", err)
|
||||
}
|
||||
|
||||
// Check if repository is empty.
|
||||
_, stderr, err = com.ExecCmdDir(repoPath, "git", "log", "-1")
|
||||
if err != nil {
|
||||
if strings.Contains(stderr, "fatal: bad default revision 'HEAD'") {
|
||||
repo.IsBare = true
|
||||
} else {
|
||||
return repo, fmt.Errorf("check bare: %v - %s", err, stderr)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if repository has master branch, if so set it to default branch.
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
|
@ -615,7 +630,7 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts C
|
|||
}
|
||||
|
||||
tmpDir := filepath.Join(os.TempDir(), "gogs-"+repo.Name+"-"+com.ToStr(time.Now().Nanosecond()))
|
||||
fmt.Println(tmpDir)
|
||||
|
||||
// Initialize repository according to user's choice.
|
||||
if opts.AutoInit {
|
||||
os.MkdirAll(tmpDir, os.ModePerm)
|
||||
|
@ -1185,9 +1200,13 @@ func GetRecentUpdatedRepositories(page int) (repos []*Repository, err error) {
|
|||
Where("is_private=?", false).Limit(setting.ExplorePagingNum).Desc("updated").Find(&repos)
|
||||
}
|
||||
|
||||
func getRepositoryCount(e Engine, u *User) (int64, error) {
|
||||
return x.Count(&Repository{OwnerID: u.Id})
|
||||
}
|
||||
|
||||
// GetRepositoryCount returns the total number of repositories of user.
|
||||
func GetRepositoryCount(u *User) (int64, error) {
|
||||
return x.Count(&Repository{OwnerID: u.Id})
|
||||
return getRepositoryCount(x, u)
|
||||
}
|
||||
|
||||
type SearchOption struct {
|
||||
|
|
178
models/user.go
|
@ -55,12 +55,13 @@ type User struct {
|
|||
Name string `xorm:"UNIQUE NOT NULL"`
|
||||
FullName string
|
||||
// Email is the primary email address (to be used for communication).
|
||||
Email string `xorm:"UNIQUE(s) NOT NULL"`
|
||||
Email string `xorm:"NOT NULL"`
|
||||
Passwd string `xorm:"NOT NULL"`
|
||||
LoginType LoginType
|
||||
LoginSource int64 `xorm:"NOT NULL DEFAULT 0"`
|
||||
LoginName string
|
||||
Type UserType `xorm:"UNIQUE(s)"`
|
||||
Type UserType
|
||||
OwnedOrgs []*User `xorm:"-"`
|
||||
Orgs []*User `xorm:"-"`
|
||||
Repos []*Repository `xorm:"-"`
|
||||
Location string
|
||||
|
@ -132,42 +133,56 @@ func (u *User) HomeLink() string {
|
|||
return setting.AppSubUrl + "/" + u.Name
|
||||
}
|
||||
|
||||
// CustomAvatarPath returns user custom avatar file path.
|
||||
func (u *User) CustomAvatarPath() string {
|
||||
return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
|
||||
}
|
||||
|
||||
// GenerateRandomAvatar generates a random avatar for user.
|
||||
func (u *User) GenerateRandomAvatar() error {
|
||||
seed := u.Email
|
||||
if len(seed) == 0 {
|
||||
seed = u.Name
|
||||
}
|
||||
|
||||
img, err := avatar.RandomImage([]byte(seed))
|
||||
if err != nil {
|
||||
return fmt.Errorf("RandomImage: %v", err)
|
||||
}
|
||||
if err = os.MkdirAll(path.Dir(u.CustomAvatarPath()), os.ModePerm); err != nil {
|
||||
return fmt.Errorf("MkdirAll: %v", err)
|
||||
}
|
||||
fw, err := os.Create(u.CustomAvatarPath())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Create: %v", err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
if err = jpeg.Encode(fw, img, nil); err != nil {
|
||||
return fmt.Errorf("Encode: %v", err)
|
||||
}
|
||||
|
||||
log.Info("New random avatar created: %d", u.Id)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *User) RelAvatarLink() string {
|
||||
defaultImgUrl := "/img/avatar_default.jpg"
|
||||
if u.Id == -1 {
|
||||
return defaultImgUrl
|
||||
}
|
||||
|
||||
imgPath := path.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
|
||||
switch {
|
||||
case u.UseCustomAvatar:
|
||||
if !com.IsExist(imgPath) {
|
||||
if !com.IsExist(u.CustomAvatarPath()) {
|
||||
return defaultImgUrl
|
||||
}
|
||||
return "/avatars/" + com.ToStr(u.Id)
|
||||
case setting.DisableGravatar, setting.OfflineMode:
|
||||
if !com.IsExist(imgPath) {
|
||||
img, err := avatar.RandomImage([]byte(u.Email))
|
||||
if err != nil {
|
||||
log.Error(3, "RandomImage: %v", err)
|
||||
return defaultImgUrl
|
||||
if !com.IsExist(u.CustomAvatarPath()) {
|
||||
if err := u.GenerateRandomAvatar(); err != nil {
|
||||
log.Error(3, "GenerateRandomAvatar: %v", err)
|
||||
}
|
||||
if err = os.MkdirAll(path.Dir(imgPath), os.ModePerm); err != nil {
|
||||
log.Error(3, "MkdirAll: %v", err)
|
||||
return defaultImgUrl
|
||||
}
|
||||
fw, err := os.Create(imgPath)
|
||||
if err != nil {
|
||||
log.Error(3, "Create: %v", err)
|
||||
return defaultImgUrl
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
if err = jpeg.Encode(fw, img, nil); err != nil {
|
||||
log.Error(3, "Encode: %v", err)
|
||||
return defaultImgUrl
|
||||
}
|
||||
log.Info("New random avatar created: %d", u.Id)
|
||||
}
|
||||
|
||||
return "/avatars/" + com.ToStr(u.Id)
|
||||
|
@ -208,11 +223,6 @@ func (u *User) ValidatePassword(passwd string) bool {
|
|||
return u.Passwd == newUser.Passwd
|
||||
}
|
||||
|
||||
// CustomAvatarPath returns user custom avatar file path.
|
||||
func (u *User) CustomAvatarPath() string {
|
||||
return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
|
||||
}
|
||||
|
||||
// UploadAvatar saves custom avatar for user.
|
||||
// FIXME: split uploads to different subdirs in case we have massive users.
|
||||
func (u *User) UploadAvatar(data []byte) error {
|
||||
|
@ -222,28 +232,27 @@ func (u *User) UploadAvatar(data []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := resize.Resize(234, 234, img, resize.NearestNeighbor)
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Id(u.Id).AllCols().Update(u); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
os.MkdirAll(setting.AvatarUploadPath, os.ModePerm)
|
||||
fw, err := os.Create(u.CustomAvatarPath())
|
||||
if err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
if err = jpeg.Encode(fw, m, nil); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -284,9 +293,13 @@ func (u *User) IsPublicMember(orgId int64) bool {
|
|||
return IsPublicMembership(orgId, u.Id)
|
||||
}
|
||||
|
||||
func (u *User) getOrganizationCount(e Engine) (int64, error) {
|
||||
return e.Where("uid=?", u.Id).Count(new(OrgUser))
|
||||
}
|
||||
|
||||
// GetOrganizationCount returns count of membership of organization of user.
|
||||
func (u *User) GetOrganizationCount() (int64, error) {
|
||||
return x.Where("uid=?", u.Id).Count(new(OrgUser))
|
||||
return u.getOrganizationCount(x)
|
||||
}
|
||||
|
||||
// GetRepositories returns all repositories that user owns, including private repositories.
|
||||
|
@ -295,6 +308,12 @@ func (u *User) GetRepositories() (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
// GetOwnedOrganizations returns all organizations that user owns.
|
||||
func (u *User) GetOwnedOrganizations() (err error) {
|
||||
u.OwnedOrgs, err = GetOwnedOrgsByUserID(u.Id)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetOrganizations returns all organizations that user belongs to.
|
||||
func (u *User) GetOrganizations() error {
|
||||
ous, err := GetOrgUsersByUserId(u.Id)
|
||||
|
@ -490,12 +509,20 @@ func ChangeUserName(u *User, newUserName string) (err error) {
|
|||
}
|
||||
|
||||
func updateUser(e Engine, u *User) error {
|
||||
u.Email = strings.ToLower(u.Email)
|
||||
has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrEmailAlreadyUsed{u.Email}
|
||||
// Organization does not need e-mail.
|
||||
if !u.IsOrganization() {
|
||||
u.Email = strings.ToLower(u.Email)
|
||||
has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrEmailAlreadyUsed{u.Email}
|
||||
}
|
||||
|
||||
if len(u.AvatarEmail) == 0 {
|
||||
u.AvatarEmail = u.Email
|
||||
}
|
||||
u.Avatar = avatar.HashEmail(u.AvatarEmail)
|
||||
}
|
||||
|
||||
u.LowerName = strings.ToLower(u.Name)
|
||||
|
@ -510,13 +537,8 @@ func updateUser(e Engine, u *User) error {
|
|||
u.Description = u.Description[:255]
|
||||
}
|
||||
|
||||
if u.AvatarEmail == "" {
|
||||
u.AvatarEmail = u.Email
|
||||
}
|
||||
u.Avatar = avatar.HashEmail(u.AvatarEmail)
|
||||
|
||||
u.FullName = base.Sanitizer.Sanitize(u.FullName)
|
||||
_, err = e.Id(u.Id).AllCols().Update(u)
|
||||
_, err := e.Id(u.Id).AllCols().Update(u)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -525,8 +547,8 @@ func UpdateUser(u *User) error {
|
|||
return updateUser(x, u)
|
||||
}
|
||||
|
||||
// DeleteBeans deletes all given beans, beans should contain delete conditions.
|
||||
func DeleteBeans(e Engine, beans ...interface{}) (err error) {
|
||||
// deleteBeans deletes all given beans, beans should contain delete conditions.
|
||||
func deleteBeans(e Engine, beans ...interface{}) (err error) {
|
||||
for i := range beans {
|
||||
if _, err = e.Delete(beans[i]); err != nil {
|
||||
return err
|
||||
|
@ -536,14 +558,12 @@ func DeleteBeans(e Engine, beans ...interface{}) (err error) {
|
|||
}
|
||||
|
||||
// FIXME: need some kind of mechanism to record failure. HINT: system notice
|
||||
// DeleteUser completely and permanently deletes everything of a user,
|
||||
// but issues/comments/pulls will be kept and shown as someone has been deleted.
|
||||
func DeleteUser(u *User) error {
|
||||
func deleteUser(e *xorm.Session, u *User) error {
|
||||
// Note: A user owns any repository or belongs to any organization
|
||||
// cannot perform delete operation.
|
||||
|
||||
// Check ownership of repository.
|
||||
count, err := GetRepositoryCount(u)
|
||||
count, err := getRepositoryCount(e, u)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetRepositoryCount: %v", err)
|
||||
} else if count > 0 {
|
||||
|
@ -551,26 +571,20 @@ func DeleteUser(u *User) error {
|
|||
}
|
||||
|
||||
// Check membership of organization.
|
||||
count, err = u.GetOrganizationCount()
|
||||
count, err = u.getOrganizationCount(e)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetOrganizationCount: %v", err)
|
||||
} else if count > 0 {
|
||||
return ErrUserHasOrgs{UID: u.Id}
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ***** START: Watch *****
|
||||
watches := make([]*Watch, 0, 10)
|
||||
if err = x.Find(&watches, &Watch{UserID: u.Id}); err != nil {
|
||||
if err = e.Find(&watches, &Watch{UserID: u.Id}); err != nil {
|
||||
return fmt.Errorf("get all watches: %v", err)
|
||||
}
|
||||
for i := range watches {
|
||||
if _, err = sess.Exec("UPDATE `repository` SET num_watches=num_watches-1 WHERE id=?", watches[i].RepoID); err != nil {
|
||||
if _, err = e.Exec("UPDATE `repository` SET num_watches=num_watches-1 WHERE id=?", watches[i].RepoID); err != nil {
|
||||
return fmt.Errorf("decrease repository watch number[%d]: %v", watches[i].RepoID, err)
|
||||
}
|
||||
}
|
||||
|
@ -578,11 +592,11 @@ func DeleteUser(u *User) error {
|
|||
|
||||
// ***** START: Star *****
|
||||
stars := make([]*Star, 0, 10)
|
||||
if err = x.Find(&stars, &Star{UID: u.Id}); err != nil {
|
||||
if err = e.Find(&stars, &Star{UID: u.Id}); err != nil {
|
||||
return fmt.Errorf("get all stars: %v", err)
|
||||
}
|
||||
for i := range stars {
|
||||
if _, err = sess.Exec("UPDATE `repository` SET num_stars=num_stars-1 WHERE id=?", stars[i].RepoID); err != nil {
|
||||
if _, err = e.Exec("UPDATE `repository` SET num_stars=num_stars-1 WHERE id=?", stars[i].RepoID); err != nil {
|
||||
return fmt.Errorf("decrease repository star number[%d]: %v", stars[i].RepoID, err)
|
||||
}
|
||||
}
|
||||
|
@ -590,17 +604,17 @@ func DeleteUser(u *User) error {
|
|||
|
||||
// ***** START: Follow *****
|
||||
followers := make([]*Follow, 0, 10)
|
||||
if err = x.Find(&followers, &Follow{UserID: u.Id}); err != nil {
|
||||
if err = e.Find(&followers, &Follow{UserID: u.Id}); err != nil {
|
||||
return fmt.Errorf("get all followers: %v", err)
|
||||
}
|
||||
for i := range followers {
|
||||
if _, err = sess.Exec("UPDATE `user` SET num_followers=num_followers-1 WHERE id=?", followers[i].UserID); err != nil {
|
||||
if _, err = e.Exec("UPDATE `user` SET num_followers=num_followers-1 WHERE id=?", followers[i].UserID); err != nil {
|
||||
return fmt.Errorf("decrease user follower number[%d]: %v", followers[i].UserID, err)
|
||||
}
|
||||
}
|
||||
// ***** END: Follow *****
|
||||
|
||||
if err = DeleteBeans(sess,
|
||||
if err = deleteBeans(e,
|
||||
&Oauth2{Uid: u.Id},
|
||||
&AccessToken{UID: u.Id},
|
||||
&Collaboration{UserID: u.Id},
|
||||
|
@ -612,34 +626,30 @@ func DeleteUser(u *User) error {
|
|||
&IssueUser{UID: u.Id},
|
||||
&EmailAddress{Uid: u.Id},
|
||||
); err != nil {
|
||||
return fmt.Errorf("DeleteBeans: %v", err)
|
||||
return fmt.Errorf("deleteUser: %v", err)
|
||||
}
|
||||
|
||||
// ***** START: PublicKey *****
|
||||
keys := make([]*PublicKey, 0, 10)
|
||||
if err = sess.Find(&keys, &PublicKey{OwnerID: u.Id}); err != nil {
|
||||
if err = e.Find(&keys, &PublicKey{OwnerID: u.Id}); err != nil {
|
||||
return fmt.Errorf("get all public keys: %v", err)
|
||||
}
|
||||
for _, key := range keys {
|
||||
if err = deletePublicKey(sess, key.ID); err != nil {
|
||||
if err = deletePublicKey(e, key.ID); err != nil {
|
||||
return fmt.Errorf("deletePublicKey: %v", err)
|
||||
}
|
||||
}
|
||||
// ***** END: PublicKey *****
|
||||
|
||||
// Clear assignee.
|
||||
if _, err = sess.Exec("UPDATE `issue` SET assignee_id=0 WHERE assignee_id=?", u.Id); err != nil {
|
||||
if _, err = e.Exec("UPDATE `issue` SET assignee_id=0 WHERE assignee_id=?", u.Id); err != nil {
|
||||
return fmt.Errorf("clear assignee: %v", err)
|
||||
}
|
||||
|
||||
if _, err = sess.Id(u.Id).Delete(new(User)); err != nil {
|
||||
if _, err = e.Id(u.Id).Delete(new(User)); err != nil {
|
||||
return fmt.Errorf("Delete: %v", err)
|
||||
}
|
||||
|
||||
if err = sess.Commit(); err != nil {
|
||||
return fmt.Errorf("Commit: %v", err)
|
||||
}
|
||||
|
||||
// FIXME: system notice
|
||||
// Note: There are something just cannot be roll back,
|
||||
// so just keep error logs of those operations.
|
||||
|
@ -651,6 +661,22 @@ func DeleteUser(u *User) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// DeleteUser completely and permanently deletes everything of a user,
|
||||
// but issues/comments/pulls will be kept and shown as someone has been deleted.
|
||||
func DeleteUser(u *User) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = deleteUser(sess, u); err != nil {
|
||||
return fmt.Errorf("deleteUser: %v", err)
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// DeleteInactivateUsers deletes all inactivate users and email addresses.
|
||||
func DeleteInactivateUsers() (err error) {
|
||||
users := make([]*User, 0, 10)
|
||||
|
|
|
@ -17,8 +17,7 @@ import (
|
|||
// \/ /_____/ \/ \/ \/ \/ \/
|
||||
|
||||
type CreateOrgForm struct {
|
||||
OrgName string `form:"org_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
|
||||
OrgName string `binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
|
||||
}
|
||||
|
||||
func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
|
@ -26,13 +25,11 @@ func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) bind
|
|||
}
|
||||
|
||||
type UpdateOrgSettingForm struct {
|
||||
OrgUserName string `form:"uname" binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
|
||||
OrgFullName string `form:"fullname" binding:"MaxSize(100)"`
|
||||
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
|
||||
Description string `form:"desc" binding:"MaxSize(255)"`
|
||||
Website string `form:"website" binding:"Url;MaxSize(100)"`
|
||||
Location string `form:"location" binding:"MaxSize(50)"`
|
||||
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
|
||||
Name string `binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"Url;MaxSize(100)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
}
|
||||
|
||||
func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
|
|
|
@ -88,12 +88,12 @@ func (f *SignInForm) Validate(ctx *macaron.Context, errs binding.Errors) binding
|
|||
// \/ \/ \/ \/ \/
|
||||
|
||||
type UpdateProfileForm struct {
|
||||
UserName string `form:"uname" binding:"Required;MaxSize(35)"`
|
||||
FullName string `form:"fullname" binding:"MaxSize(100)"`
|
||||
Email string `form:"email" binding:"Required;Email;MaxSize(254)"`
|
||||
Website string `form:"website" binding:"Url;MaxSize(100)"`
|
||||
Location string `form:"location" binding:"MaxSize(50)"`
|
||||
Avatar string `form:"avatar" binding:"Required;Email;MaxSize(254)"`
|
||||
Name string `binding:"Required;MaxSize(35)"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
Website string `binding:"Url;MaxSize(100)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
Gravatar string `binding:"Required;Email;MaxSize(254)"`
|
||||
}
|
||||
|
||||
func (f *UpdateProfileForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
|
@ -101,8 +101,8 @@ func (f *UpdateProfileForm) Validate(ctx *macaron.Context, errs binding.Errors)
|
|||
}
|
||||
|
||||
type UploadAvatarForm struct {
|
||||
Enable bool `form:"enable"`
|
||||
Avatar *multipart.FileHeader `form:"avatar"`
|
||||
Enable bool
|
||||
Avatar *multipart.FileHeader
|
||||
}
|
||||
|
||||
func (f *UploadAvatarForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
|
||||
|
|
|
@ -76,9 +76,8 @@ func ToUtf8WithErr(content []byte) (error, string) {
|
|||
}
|
||||
|
||||
encoding, _ := charset.Lookup(charsetLabel)
|
||||
|
||||
if encoding == nil {
|
||||
return fmt.Errorf("unknow char decoder %s", charsetLabel), string(content)
|
||||
return fmt.Errorf("unknown char decoder %s", charsetLabel), string(content)
|
||||
}
|
||||
|
||||
result, n, err := transform.String(encoding.NewDecoder(), string(content))
|
||||
|
|
|
@ -48,6 +48,7 @@ type Message struct {
|
|||
To []string
|
||||
From string
|
||||
Subject string
|
||||
ReplyTo string
|
||||
Body string
|
||||
Type string
|
||||
Massive bool
|
||||
|
@ -63,7 +64,7 @@ func (m Message) Content() string {
|
|||
}
|
||||
|
||||
// create mail content
|
||||
content := "From: " + m.From + "\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
|
||||
content := "From: " + m.From + "\r\nReply-To: " + m.ReplyTo + "\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
|
||||
return content
|
||||
}
|
||||
|
||||
|
@ -252,7 +253,8 @@ func SendAsync(msg *Message) {
|
|||
func NewHtmlMessage(To []string, From, Subject, Body string) Message {
|
||||
return Message{
|
||||
To: To,
|
||||
From: From,
|
||||
From: setting.MailService.From,
|
||||
ReplyTo: From,
|
||||
Subject: Subject,
|
||||
Body: Body,
|
||||
Type: "html",
|
||||
|
|
|
@ -201,6 +201,11 @@ func ExecPath() (string, error) {
|
|||
|
||||
// WorkDir returns absolute path of work directory.
|
||||
func WorkDir() (string, error) {
|
||||
wd := os.Getenv("GOGS_WORK_DIR")
|
||||
if len(wd) > 0 {
|
||||
return wd, nil
|
||||
}
|
||||
|
||||
execPath, err := ExecPath()
|
||||
if err != nil {
|
||||
return execPath, err
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"CodeKitInfo": "This is a CodeKit 2.x project configuration file. It is designed to sync project settings across multiple machines. MODIFYING THE CONTENTS OF THIS FILE IS A POOR LIFE DECISION. If you do so, you will likely cause CodeKit to crash. This file is not useful unless accompanied by the project that created it in CodeKit 2. This file is not backwards-compatible with CodeKit 1.x. For more information, see: http:\/\/incident57.com\/codekit",
|
||||
"creatorBuild": "18493",
|
||||
"creatorBuild": "19051",
|
||||
"files": {
|
||||
"\/css\/dropzone-4.0.1.css": {
|
||||
"fileType": 16,
|
||||
|
@ -83,6 +83,17 @@
|
|||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0
|
||||
},
|
||||
"\/css\/themes\/default\/assets\/images\/flags.png": {
|
||||
"fileType": 32768,
|
||||
"ignore": 0,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"initialSize": 28123,
|
||||
"inputAbbreviatedPath": "\/css\/themes\/default\/assets\/images\/flags.png",
|
||||
"outputAbbreviatedPath": "\/css\/themes\/default\/assets\/images\/flags.png",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0,
|
||||
"processed": 0
|
||||
},
|
||||
"\/img\/404.png": {
|
||||
"fileType": 32768,
|
||||
"ignore": 0,
|
||||
|
@ -169,7 +180,7 @@
|
|||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0,
|
||||
"outputStyle": 1,
|
||||
"syntaxCheckerStyle": 1
|
||||
"syntaxCheckerStyle": 0
|
||||
},
|
||||
"\/js\/jquery-1.11.3.min.js": {
|
||||
"fileType": 64,
|
||||
|
@ -193,6 +204,17 @@
|
|||
"outputStyle": 1,
|
||||
"syntaxCheckerStyle": 1
|
||||
},
|
||||
"\/js\/libs\/emojify-1.1.0.min.js": {
|
||||
"fileType": 64,
|
||||
"ignore": 0,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/js\/libs\/emojify-1.1.0.min.js",
|
||||
"outputAbbreviatedPath": "\/js\/libs\/min\/emojify-1.1.0.min-min.js",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0,
|
||||
"outputStyle": 1,
|
||||
"syntaxCheckerStyle": 1
|
||||
},
|
||||
"\/js\/libs\/highlight-8.7.pack.js": {
|
||||
"fileType": 64,
|
||||
"ignore": 0,
|
||||
|
@ -308,6 +330,26 @@
|
|||
"strictMath": 0,
|
||||
"strictUnits": 0
|
||||
},
|
||||
"\/less\/_emojify.less": {
|
||||
"allowInsecureImports": 0,
|
||||
"createSourceMap": 0,
|
||||
"disableJavascript": 0,
|
||||
"fileType": 1,
|
||||
"ieCompatibility": 1,
|
||||
"ignore": 1,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"inputAbbreviatedPath": "\/less\/_emojify.less",
|
||||
"outputAbbreviatedPath": "\/css\/_emojify.css",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 0,
|
||||
"outputStyle": 0,
|
||||
"relativeURLS": 0,
|
||||
"shouldRunAutoprefixer": 0,
|
||||
"shouldRunBless": 0,
|
||||
"strictImports": 0,
|
||||
"strictMath": 0,
|
||||
"strictUnits": 0
|
||||
},
|
||||
"\/less\/_explore.less": {
|
||||
"allowInsecureImports": 0,
|
||||
"createSourceMap": 0,
|
||||
|
@ -500,7 +542,7 @@
|
|||
"outputAbbreviatedPath": "\/css\/gogs.min.css",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
"outputPathIsSetByUser": 1,
|
||||
"outputStyle": 2,
|
||||
"outputStyle": 1,
|
||||
"relativeURLS": 0,
|
||||
"shouldRunAutoprefixer": 0,
|
||||
"shouldRunBless": 0,
|
||||
|
@ -564,8 +606,8 @@
|
|||
},
|
||||
"\/ng\/js\/gogs.js": {
|
||||
"fileType": 64,
|
||||
"ignore": 0,
|
||||
"ignoreWasSetByUser": 0,
|
||||
"ignore": 1,
|
||||
"ignoreWasSetByUser": 1,
|
||||
"inputAbbreviatedPath": "\/ng\/js\/gogs.js",
|
||||
"outputAbbreviatedPath": "\/ng\/js\/min\/gogs-min.js",
|
||||
"outputPathIsOutsideProject": 0,
|
||||
|
@ -1415,6 +1457,10 @@
|
|||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"futurehostile": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"globalstrict": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
|
@ -1503,6 +1549,10 @@
|
|||
"active": 1,
|
||||
"flagValue": -1
|
||||
},
|
||||
"nocomma": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"node": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
|
@ -1603,6 +1653,10 @@
|
|||
"active": 1,
|
||||
"flagValue": -1
|
||||
},
|
||||
"varstmt": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"withstmt": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
|
@ -1621,10 +1675,6 @@
|
|||
}
|
||||
},
|
||||
"jsLintFlags2": {
|
||||
"ass": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"bitwise": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
|
@ -1633,15 +1683,7 @@
|
|||
"active": 1,
|
||||
"flagValue": -1
|
||||
},
|
||||
"closure": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"continue": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"debug": {
|
||||
"couch": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
|
@ -1649,75 +1691,27 @@
|
|||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"eqeq": {
|
||||
"es6": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"evil": {
|
||||
"eval": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"forin": {
|
||||
"for": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"indent": {
|
||||
"active": 0,
|
||||
"flagValue": 4
|
||||
},
|
||||
"maxlen": {
|
||||
"active": 0,
|
||||
"flagValue": 150
|
||||
},
|
||||
"newcap": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"node": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"nomen": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"plusplus": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"properties": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"regexp": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"rhino": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"sloppy": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"stupid": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"sub": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"todo": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"unparam": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"vars": {
|
||||
"this": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
|
@ -1726,6 +1720,14 @@
|
|||
"flagValue": -1
|
||||
}
|
||||
},
|
||||
"jsonAutoOutputPathEnabled": 0,
|
||||
"jsonAutoOutputPathFilenamePattern": "*-min.json",
|
||||
"jsonAutoOutputPathRelativePath": "",
|
||||
"jsonAutoOutputPathReplace1": "",
|
||||
"jsonAutoOutputPathReplace2": "",
|
||||
"jsonAutoOutputPathStyle": 0,
|
||||
"jsonOrderOutput": 0,
|
||||
"jsonOutputStyle": 1,
|
||||
"kitAutoOutputPathEnabled": 1,
|
||||
"kitAutoOutputPathFilenamePattern": "*.html",
|
||||
"kitAutoOutputPathRelativePath": "",
|
||||
|
@ -1753,9 +1755,18 @@
|
|||
"markdownAutoOutputPathReplace1": "",
|
||||
"markdownAutoOutputPathReplace2": "",
|
||||
"markdownAutoOutputPathStyle": 0,
|
||||
"markdownCriticStyle": 0,
|
||||
"markdownEnableFootnotes": 0,
|
||||
"markdownEnableSmartyPants": 1,
|
||||
"markdownExpandTabs": 1,
|
||||
"markdownEnableLabels": 1,
|
||||
"markdownEnableSmartQuotes": 1,
|
||||
"markdownEscapeLineBreaks": 0,
|
||||
"markdownMaskEmailAddresses": 1,
|
||||
"markdownOutputFormat": 0,
|
||||
"markdownOutputStyle": 0,
|
||||
"markdownParseMetadata": 1,
|
||||
"markdownProcessHTML": 0,
|
||||
"markdownRandomFootnoteNumbers": 0,
|
||||
"markdownUseCompatibilityMode": 0,
|
||||
"reloadFileURLs": 0,
|
||||
"sassAutoOutputPathEnabled": 1,
|
||||
"sassAutoOutputPathFilenamePattern": "*.css",
|
||||
|
@ -1770,7 +1781,7 @@
|
|||
"sassUseLibsass": 0,
|
||||
"shouldRunAutoprefixer": 0,
|
||||
"shouldRunBless": 0,
|
||||
"skippedItemsString": ".svn, .git, .hg, log, _logs, _cache, cache, logs, node_modules",
|
||||
"skippedItemsString": "_cache, logs, _logs, cache, \/img\/emoji, .git, log, node_modules, .svn, .hg",
|
||||
"slimAutoOutputPathEnabled": 1,
|
||||
"slimAutoOutputPathFilenamePattern": "*.html",
|
||||
"slimAutoOutputPathRelativePath": "",
|
||||
|
@ -1814,6 +1825,10 @@
|
|||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"bare-returns": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"booleans": {
|
||||
"active": 1,
|
||||
"flagValue": -1
|
||||
|
@ -1894,6 +1909,10 @@
|
|||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"keep_fnames": {
|
||||
"active": 0,
|
||||
"flagValue": -1
|
||||
},
|
||||
"loops": {
|
||||
"active": 1,
|
||||
"flagValue": -1
|
||||
|
|
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 4.7 KiB |