123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- // Copyright 2020 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 notify
-
- import (
- "net/http"
- "strings"
- "time"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/context"
- "code.gitea.io/gitea/modules/convert"
- "code.gitea.io/gitea/modules/log"
- )
-
- func statusStringToNotificationStatus(status string) models.NotificationStatus {
- switch strings.ToLower(strings.TrimSpace(status)) {
- case "unread":
- return models.NotificationStatusUnread
- case "read":
- return models.NotificationStatusRead
- case "pinned":
- return models.NotificationStatusPinned
- default:
- return 0
- }
- }
-
- func statusStringsToNotificationStatuses(statuses []string, defaultStatuses []string) []models.NotificationStatus {
- if len(statuses) == 0 {
- statuses = defaultStatuses
- }
- results := make([]models.NotificationStatus, 0, len(statuses))
- for _, status := range statuses {
- notificationStatus := statusStringToNotificationStatus(status)
- if notificationStatus > 0 {
- results = append(results, notificationStatus)
- }
- }
- return results
- }
-
- // ListRepoNotifications list users's notification threads on a specific repo
- func ListRepoNotifications(ctx *context.APIContext) {
- // swagger:operation GET /repos/{owner}/{repo}/notifications notification notifyGetRepoList
- // ---
- // summary: List users's notification threads on a specific repo
- // consumes:
- // - application/json
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: all
- // in: query
- // description: If true, show notifications marked as read. Default value is false
- // type: boolean
- // - name: status-types
- // in: query
- // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned"
- // type: array
- // collectionFormat: multi
- // items:
- // type: string
- // - name: subject-type
- // in: query
- // description: "filter notifications by subject type"
- // type: array
- // collectionFormat: multi
- // items:
- // type: string
- // enum: [issue,pull,commit,repository]
- // - name: since
- // in: query
- // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format
- // type: string
- // format: date-time
- // - name: before
- // in: query
- // description: Only show notifications updated before the given time. This is a timestamp in RFC 3339 format
- // type: string
- // format: date-time
- // - name: page
- // in: query
- // description: page number of results to return (1-based)
- // type: integer
- // - name: limit
- // in: query
- // description: page size of results
- // type: integer
- // responses:
- // "200":
- // "$ref": "#/responses/NotificationThreadList"
- opts := getFindNotificationOptions(ctx)
- if ctx.Written() {
- return
- }
- opts.RepoID = ctx.Repo.Repository.ID
-
- totalCount, err := models.CountNotifications(opts)
- if err != nil {
- ctx.InternalServerError(err)
- return
- }
-
- nl, err := models.GetNotifications(opts)
- if err != nil {
- ctx.InternalServerError(err)
- return
- }
- err = nl.LoadAttributes()
- if err != nil {
- ctx.InternalServerError(err)
- return
- }
-
- ctx.SetTotalCountHeader(totalCount)
-
- ctx.JSON(http.StatusOK, convert.ToNotifications(nl))
- }
-
- // ReadRepoNotifications mark notification threads as read on a specific repo
- func ReadRepoNotifications(ctx *context.APIContext) {
- // swagger:operation PUT /repos/{owner}/{repo}/notifications notification notifyReadRepoList
- // ---
- // summary: Mark notification threads as read, pinned or unread on a specific repo
- // consumes:
- // - application/json
- // produces:
- // - application/json
- // parameters:
- // - name: owner
- // in: path
- // description: owner of the repo
- // type: string
- // required: true
- // - name: repo
- // in: path
- // description: name of the repo
- // type: string
- // required: true
- // - name: all
- // in: query
- // description: If true, mark all notifications on this repo. Default value is false
- // type: string
- // required: false
- // - name: status-types
- // in: query
- // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread."
- // type: array
- // collectionFormat: multi
- // items:
- // type: string
- // required: false
- // - name: to-status
- // in: query
- // description: Status to mark notifications as. Defaults to read.
- // type: string
- // required: false
- // - name: last_read_at
- // in: query
- // description: Describes the last point that notifications were checked. Anything updated since this time will not be updated.
- // type: string
- // format: date-time
- // required: false
- // responses:
- // "205":
- // "$ref": "#/responses/empty"
-
- lastRead := int64(0)
- qLastRead := ctx.FormTrim("last_read_at")
- if len(qLastRead) > 0 {
- tmpLastRead, err := time.Parse(time.RFC3339, qLastRead)
- if err != nil {
- ctx.InternalServerError(err)
- return
- }
- if !tmpLastRead.IsZero() {
- lastRead = tmpLastRead.Unix()
- }
- }
-
- opts := &models.FindNotificationOptions{
- UserID: ctx.User.ID,
- RepoID: ctx.Repo.Repository.ID,
- UpdatedBeforeUnix: lastRead,
- }
-
- if !ctx.FormBool("all") {
- statuses := ctx.FormStrings("status-types")
- opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"})
- log.Error("%v", opts.Status)
- }
- nl, err := models.GetNotifications(opts)
- if err != nil {
- ctx.InternalServerError(err)
- return
- }
-
- targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status"))
- if targetStatus == 0 {
- targetStatus = models.NotificationStatusRead
- }
-
- for _, n := range nl {
- err := models.SetNotificationStatus(n.ID, ctx.User, targetStatus)
- if err != nil {
- ctx.InternalServerError(err)
- return
- }
- ctx.Status(http.StatusResetContent)
- }
-
- ctx.Status(http.StatusResetContent)
- }
|