// Copyright 2017 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models import ( "time" "code.gitea.io/gitea/modules/setting" "xorm.io/builder" ) // TrackedTime represents a time that was spent for a specific issue. type TrackedTime struct { ID int64 `xorm:"pk autoincr"` IssueID int64 `xorm:"INDEX"` Issue *Issue `xorm:"-"` UserID int64 `xorm:"INDEX"` User *User `xorm:"-"` Created time.Time `xorm:"-"` CreatedUnix int64 `xorm:"created"` Time int64 `xorm:"NOT NULL"` Deleted bool `xorm:"NOT NULL DEFAULT false"` } // TrackedTimeList is a List of TrackedTime's type TrackedTimeList []*TrackedTime // AfterLoad is invoked from XORM after setting the values of all fields of this object. func (t *TrackedTime) AfterLoad() { t.Created = time.Unix(t.CreatedUnix, 0).In(setting.DefaultUILocation) } // LoadAttributes load Issue, User func (t *TrackedTime) LoadAttributes() (err error) { return t.loadAttributes(x) } func (t *TrackedTime) loadAttributes(e Engine) (err error) { if t.Issue == nil { t.Issue, err = getIssueByID(e, t.IssueID) if err != nil { return } err = t.Issue.loadRepo(e) if err != nil { return } } if t.User == nil { t.User, err = getUserByID(e, t.UserID) if err != nil { return } } return } // LoadAttributes load Issue, User func (tl TrackedTimeList) LoadAttributes() (err error) { for _, t := range tl { if err = t.LoadAttributes(); err != nil { return err } } return } // FindTrackedTimesOptions represent the filters for tracked times. If an ID is 0 it will be ignored. type FindTrackedTimesOptions struct { ListOptions IssueID int64 UserID int64 RepositoryID int64 MilestoneID int64 CreatedAfterUnix int64 CreatedBeforeUnix int64 } // ToCond will convert each condition into a xorm-Cond func (opts *FindTrackedTimesOptions) ToCond() builder.Cond { cond := builder.NewCond().And(builder.Eq{"tracked_time.deleted": false}) if opts.IssueID != 0 { cond = cond.And(builder.Eq{"issue_id": opts.IssueID}) } if opts.UserID != 0 { cond = cond.And(builder.Eq{"user_id": opts.UserID}) } if opts.RepositoryID != 0 { cond = cond.And(builder.Eq{"issue.repo_id": opts.RepositoryID}) } if opts.MilestoneID != 0 { cond = cond.And(builder.Eq{"issue.milestone_id": opts.MilestoneID}) } if opts.CreatedAfterUnix != 0 { cond = cond.And(builder.Gte{"tracked_time.created_unix": opts.CreatedAfterUnix}) } if opts.CreatedBeforeUnix != 0 { cond = cond.And(builder.Lte{"tracked_time.created_unix": opts.CreatedBeforeUnix}) } return cond } // ToSession will convert the given options to a xorm Session by using the conditions from ToCond and joining with issue table if required func (opts *FindTrackedTimesOptions) ToSession(e Engine) Engine { sess := e if opts.RepositoryID > 0 || opts.MilestoneID > 0 { sess = e.Join("INNER", "issue", "issue.id = tracked_time.issue_id") } sess = sess.Where(opts.ToCond()) if opts.Page != 0 { sess = opts.setEnginePagination(sess) } return sess } func getTrackedTimes(e Engine, options FindTrackedTimesOptions) (trackedTimes TrackedTimeList, err error) { err = options.ToSession(e).Find(&trackedTimes) return } // GetTrackedTimes returns all tracked times that fit to the given options. func GetTrackedTimes(opts FindTrackedTimesOptions) (TrackedTimeList, error) { return getTrackedTimes(x, opts) } func getTrackedSeconds(e Engine, opts FindTrackedTimesOptions) (trackedSeconds int64, err error) { return opts.ToSession(e).SumInt(&TrackedTime{}, "time") } // GetTrackedSeconds return sum of seconds func GetTrackedSeconds(opts FindTrackedTimesOptions) (int64, error) { return getTrackedSeconds(x, opts) } // AddTime will add the given time (in seconds) to the issue func AddTime(user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return nil, err } t, err := addTime(sess, user, issue, amount, created) if err != nil { return nil, err } if err := issue.loadRepo(sess); err != nil { return nil, err } if _, err := createComment(sess, &CreateCommentOptions{ Issue: issue, Repo: issue.Repo, Doer: user, Content: SecToTime(amount), Type: CommentTypeAddTimeManual, }); err != nil { return nil, err } return t, sess.Commit() } func addTime(e Engine, user *User, issue *Issue, amount int64, created time.Time) (*TrackedTime, error) { if created.IsZero() { created = time.Now() } tt := &TrackedTime{ IssueID: issue.ID, UserID: user.ID, Time: amount, Created: created, } if _, err := e.Insert(tt); err != nil { return nil, err } return tt, nil } // TotalTimes returns the spent time for each user by an issue func TotalTimes(options FindTrackedTimesOptions) (map[*User]string, error) { trackedTimes, err := GetTrackedTimes(options) if err != nil { return nil, err } //Adding total time per user ID totalTimesByUser := make(map[int64]int64) for _, t := range trackedTimes { totalTimesByUser[t.UserID] += t.Time } totalTimes := make(map[*User]string) //Fetching User and making time human readable for userID, total := range totalTimesByUser { user, err := GetUserByID(userID) if err != nil { if IsErrUserNotExist(err) { continue } return nil, err } totalTimes[user] = SecToTime(total) } return totalTimes, nil } // DeleteIssueUserTimes deletes times for issue func DeleteIssueUserTimes(issue *Issue, user *User) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } opts := FindTrackedTimesOptions{ IssueID: issue.ID, UserID: user.ID, } removedTime, err := deleteTimes(sess, opts) if err != nil { return err } if removedTime == 0 { return ErrNotExist{} } if err := issue.loadRepo(sess); err != nil { return err } if _, err := createComment(sess, &CreateCommentOptions{ Issue: issue, Repo: issue.Repo, Doer: user, Content: "- " + SecToTime(removedTime), Type: CommentTypeDeleteTimeManual, }); err != nil { return err } return sess.Commit() } // DeleteTime delete a specific Time func DeleteTime(t *TrackedTime) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } if err := t.loadAttributes(sess); err != nil { return err } if err := deleteTime(sess, t); err != nil { return err } if _, err := createComment(sess, &CreateCommentOptions{ Issue: t.Issue, Repo: t.Issue.Repo, Doer: t.User, Content: "- " + SecToTime(t.Time), Type: CommentTypeDeleteTimeManual, }); err != nil { return err } return sess.Commit() } func deleteTimes(e Engine, opts FindTrackedTimesOptions) (removedTime int64, err error) { removedTime, err = getTrackedSeconds(e, opts) if err != nil || removedTime == 0 { return } _, err = opts.ToSession(e).Table("tracked_time").Cols("deleted").Update(&TrackedTime{Deleted: true}) return } func deleteTime(e Engine, t *TrackedTime) error { if t.Deleted { return ErrNotExist{ID: t.ID} } t.Deleted = true _, err := e.ID(t.ID).Cols("deleted").Update(t) return err } // GetTrackedTimeByID returns raw TrackedTime without loading attributes by id func GetTrackedTimeByID(id int64) (*TrackedTime, error) { time := new(TrackedTime) has, err := x.ID(id).Get(time) if err != nil { return nil, err } else if !has { return nil, ErrNotExist{ID: id} } return time, nil } e-signing-crl Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
summaryrefslogtreecommitdiffstats
path: root/apps/files/l10n/es_MX.json
blob: 628181c65569c51de2d9d989cf6a13ddedbc234f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
{ "translations": {
    "Storage is temporarily not available" : "El almacenamiento no está  disponible temporalmente ",
    "Storage invalid" : "El almacenamiento es inválido",
    "Unknown error" : "Se presentó un error desconocido",
    "All files" : "Todos los archivos",
    "Recent" : "Reciente",
    "File could not be found" : "No fue posible encontrar el archivo",
    "Home" : "Inicio",
    "Close" : "Cerrar",
    "Favorites" : "Favoritos",
    "Could not create folder \"{dir}\"" : "No fue posible crear la carpeta \"{dir}\"",
    "Upload cancelled." : "Carga cancelada.",
    "Unable to upload {filename} as it is a directory or has 0 bytes" : "No fue posible cargar {filename} ya que es una carpeta o tiene un tamaño de 0 bytes",
    "Not enough free space, you are uploading {size1} but only {size2} is left" : "No cuenta con suficiente espacio disponible, usted se encuentra cargando {size1} pero sólo cuenta con {size2} disponible",
    "Target folder \"{dir}\" does not exist any more" : "La carpeta destino \"{dir}\" ya no existe",
    "Not enough free space" : "No cuenta con suficiente espacio disponible",
    "Uploading..." : "Cargando...",
    "..." : "...",
    "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} de {totalSize} ({bitrate})",
    "Actions" : "Acciones",
    "Download" : "Descargar",
    "Rename" : "Renombrar",
    "Move" : "Mover",
    "Target folder" : "Carpeta destino",
    "Delete" : "Borrar",
    "Disconnect storage" : "Desconectar almacenamiento",
    "Unshare" : "Dejar de compartir",
    "Could not load info for file \"{file}\"" : "No fue posible cargar información para el archivo \"{file}\"",
    "Files" : "Archivos",
    "Details" : "Detalles",
    "Select" : "Seleccionar",
    "Pending" : "Pendiente",
    "Unable to determine date" : "No fue posible determinar la fecha",
    "This operation is forbidden" : "Esta operación está prohibida",
    "This directory is unavailable, please check the logs or contact the administrator" : "Esta carpeta no está disponible, favor de verficiar las bitácoras o contacte al administrador",
    "Could not move \"{file}\", target exists" : "No fue posible mover \"{file}\", el destino ya existe",
    "Could not move \"{file}\"" : "No fue posible mover \"{file}\"",
    "{newName} already exists" : "{newName} ya existe",
    "Could not rename \"{fileName}\", it does not exist any more" : "No fue posible renombrar \"{fileName}\", ya no existe",
    "The name \"{targetName}\" is already used in the folder \"{dir}\". Please choose a different name." : "El nombre \"{targetName}\" ya está en uso en la carpeta \"{dir}\". Favor de elegir un nombre diferete. ",
    "Could not rename \"{fileName}\"" : "No fue posible renombrar \"{fileName}\"",
    "Could not create file \"{file}\"" : "No fue posible crear el archivo \"{file}\"",
    "Could not create file \"{file}\" because it already exists" : "No fue posible crear el archivo\"{file}\" porque ya existe",
    "Could not create folder \"{dir}\" because it already exists" : "No fue posible crear la carpeta \"{dir}\" porque ya existe",
    "Error deleting file \"{fileName}\"." : "Se presentó un error al borrar el archivo \"{fileName}\".",
    "No search results in other folders for {tag}{filter}{endtag}" : "No se encontraron resultados en otras carpetas para  {tag}{filter}{endtag}",
    "Name" : "Nombre",
    "Size" : "Tamaño",
    "Modified" : "Modificado",
    "_%n folder_::_%n folders_" : ["%n carpeta","%n carpetas"],
    "_%n file_::_%n files_" : ["%n archivo","%n archivos"],
    "{dirs} and {files}" : "{dirs} y {files}",
    "_including %n hidden_::_including %n hidden_" : ["incluyendo %n escondido","incluyendo %n escondidos"],
    "You don’t have permission to upload or create files here" : "Usted no cuenta con los permisos para cargar o crear archivos aquí",
    "_Uploading %n file_::_Uploading %n files_" : ["Subiendo %n archivo","Cargando %n archivos"],
    "New" : "Nuevo",
    "\"{name}\" is an invalid file name." : "\"{name}\" es un nombre de archivo inválido. ",
    "File name cannot be empty." : "El nombre de archivo no puede estar vacío.",
    "\"{name}\" is not an allowed filetype" : "\"{name}\" es un tipo de archivo no permitido",
    "Storage of {owner} is full, files can not be updated or synced anymore!" : "El espacio de {owner} está lleno. ¡Los archivos ya no se pueden actualizar o sincronizar!",
    "Your storage is full, files can not be updated or synced anymore!" : "Su espacio está lleno. ¡Los archivos ya no se pueden actualizar o sincronizar!",
    "Storage of {owner} is almost full ({usedSpacePercent}%)" : "El espacio de {owner} está casi lleno ({usedSpacePercent}%)",
    "Your storage is almost full ({usedSpacePercent}%)" : "Su espacio está casi lleno ({usedSpacePercent}%)",
    "_matches '{filter}'_::_match '{filter}'_" : ["coincide '{filter}'","coinciden '{filter}'"],
    "View in folder" : "Ver en la carpeta",
    "Path" : "Ruta",
    "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"],
    "Favorited" : "Marcado como favorito",
    "Favorite" : "Favorito",
    "Copy direct link (only works for users who have access to this file/folder)" : "Copiar liga directa (sólo funciona para usuarios que tienen acceso a este archivo/carpeta)",
    "Folder" : "Carpeta",
    "New folder" : "Carpeta nueva",
    "Upload" : "Cargar",
    "An error occurred while trying to update the tags" : "Se presentó un error al intentar actualizar la etiqueta",
    "Added to favorites" : "Agregado a los favoritos",
    "Removed from favorites" : "Eliminado de los favoritos",
    "You added {file} to your favorites" : "Usted agregó {file} a sus favoritos",
    "You removed {file} from your favorites" : "Usted eliminó {file} de sus favoritos",
    "File changes" : "Cambios al archivo",
    "Created by {user}" : "Creado por {user}",
    "Changed by {user}" : "Cambiado por {user}",
    "Deleted by {user}" : "Borrado por {user}",
    "Restored by {user}" : "Restaurado por {user}",
    "Renamed by {user}" : "Renombrado por {user}",
    "Moved by {user}" : "Movido por {user}",
    "You created {file}" : "Usted creó {file}",
    "{user} created {file}" : "{user} creó {file}",
    "{file} was created in a public folder" : "{file} fue creado en una carpeta pública",
    "You changed {file}" : "Usted cambió {file}",
    "{user} changed {file}" : "{user} cambió {file}",
    "You deleted {file}" : "Usted borró {file}",
    "{user} deleted {file}" : "{user} borró {file}",
    "You restored {file}" : "Usted restauró {file}",
    "{user} restored {file}" : "{user} restauró {file}",
    "You renamed {oldfile} to {newfile}" : "Usted renombró  {oldfile} como {newfile}",
    "{user} renamed {oldfile} to {newfile}" : "{user} renombró {oldfile} como {newfile}",
    "You moved {oldfile} to {newfile}" : "Usted movió {oldfile} a {newfile}",
    "{user} moved {oldfile} to {newfile}" : "{user} movió {oldfile} a {newfile}",
    "A file has been added to or removed from your <strong>favorites</strong>" : "Un archivo ha sido agregado o eliminado de sus strong>favoritos</strong>",
    "A file or folder has been <strong>changed</strong> or <strong>renamed</strong>" : "Un archivo o carpeta ha sido <strong>cambiado </strong> o <strong>renombrado</strong>",
    "A new file or folder has been <strong>created</strong>" : "Un nuevo archivo ha sido <strong>creado</strong>",
    "A new file or folder has been <strong>deleted</strong>" : "Un nuevo archivo  ha sido <strong>borrado</strong>",
    "Limit notifications about creation and changes to your <strong>favorite files</strong> <em>(Stream only)</em>" : "Limite las notificación de la creación y cambios a sus <strong>archivos favoritos</strong> <em>(sólo flujo)</em>",
    "A new file or folder has been <strong>restored</strong>" : "Un nuevo archivo ha sido <strong>restaurado</strong>",
    "Upload (max. %s)" : "Cargar (max. %s)",
    "File handling" : "Administración de archivos",
    "Maximum upload size" : "Tamaño máximo de carga",
    "max. possible: " : "max. posible:",
    "Save" : "Guardar",
    "With PHP-FPM it might take 5 minutes for changes to be applied." : "Con PHP-FPM podría tomar 5 minutos para que los cambios apliquen. ",
    "Missing permissions to edit from here." : "Faltan privilegios para editar desde aquí. ",
    "Settings" : "Ajustes",
    "Show hidden files" : "Mostrar archivos ocultos",
    "WebDAV" : "WebDAV",
    "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">access your Files via WebDAV</a>" : "Use esta dirección para <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">acceder sus archivos vía WebDAV</a>",
    "No files in here" : "No hay archivos aquí",
    "Upload some content or sync with your devices!" : "¡Cargue algún contenido o sincronice con sus dispositivos!",
    "No entries found in this folder" : "No se encontraron elementos en esta carpeta",
    "Select all" : "Seleccionar todo",
    "Upload too large" : "La carga es demasido grande",
    "The files you are trying to upload exceed the maximum size for file uploads on this server." : "Los archivos que está intentando cargar sobrepasan el tamaño máximo permitido para la carga de archivos en este servidor.",
    "Files and folders you mark as favorite will show up here" : "Los archivos y carpetas que marque como favortios se mostrarán aquí. ",
    "Shared with you" : "Compartido con usted",
    "Shared with others" : "Compartido con otros",
    "Shared by link" : "Compartido por liga",
    "Tags" : "Etiquetas",
    "Deleted files" : "Archivos borrados",
    "Text file" : "Archivo de texto",
    "New text file.txt" : "Nuevo ArchivoDeTexto.txt",
    "_{hours}:{minutes}:{seconds} hour left_::_{hours}:{minutes}:{seconds} hours left_" : ["falta {hours}:{minutes}:{seconds} hora","faltan {hours}:{minutes}:{seconds} horas"],
    "{hours}:{minutes}h" : "{hours}:{minutes}h",
    "_{minutes}:{seconds} minute left_::_{minutes}:{seconds} minutes left_" : ["falta {minutes}:{seconds} minuto","faltan {minutes}:{seconds} minutos"],
    "{minutes}:{seconds}m" : "{minutes}:{seconds}m",
    "_{seconds} second left_::_{seconds} seconds left_" : ["falta {seconds} segundo","faltan {seconds} segundos"],
    "{seconds}s" : "{seconds}s",
    "Any moment now..." : "En cualquier momento...",
    "Soon..." : "Pronto...",
    "File upload is in progress. Leaving the page now will cancel the upload." : "La carga del archivo está en curso. El salir de la página ahora, la cancelará. ",
    "Copy local link" : "Copiar liga local",
    "No favorites" : "No hay favoritos"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}