2019-12-12 07:23:05 +03:00
// Copyright 2019 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 repo
import (
2020-03-08 20:46:24 +03:00
"errors"
2019-12-20 20:07:12 +03:00
"net/http"
2019-12-12 07:23:05 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
2020-01-24 22:00:29 +03:00
"code.gitea.io/gitea/routers/api/v1/utils"
2019-12-12 07:23:05 +03:00
)
// StartIssueStopwatch creates a stopwatch for the given issue.
func StartIssueStopwatch ( ctx * context . APIContext ) {
// swagger:operation POST /repos/{owner}/{repo}/issues/{index}/stopwatch/start issue issueStartStopWatch
// ---
// summary: Start stopwatch on an issue.
// 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: index
// in: path
// description: index of the issue to create the stopwatch on
// type: integer
// format: int64
// required: true
// responses:
// "201":
// "$ref": "#/responses/empty"
// "403":
// description: Not repo writer, user does not have rights to toggle stopwatch
// "404":
2019-12-20 20:07:12 +03:00
// "$ref": "#/responses/notFound"
2019-12-12 07:23:05 +03:00
// "409":
// description: Cannot start a stopwatch again if it already exists
2019-12-20 20:07:12 +03:00
2019-12-12 07:23:05 +03:00
issue , err := prepareIssueStopwatch ( ctx , false )
if err != nil {
return
}
if err := models . CreateOrStopIssueStopwatch ( ctx . User , issue ) ; err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "CreateOrStopIssueStopwatch" , err )
2019-12-12 07:23:05 +03:00
return
}
2019-12-20 20:07:12 +03:00
ctx . Status ( http . StatusCreated )
2019-12-12 07:23:05 +03:00
}
// StopIssueStopwatch stops a stopwatch for the given issue.
func StopIssueStopwatch ( ctx * context . APIContext ) {
// swagger:operation POST /repos/{owner}/{repo}/issues/{index}/stopwatch/stop issue issueStopStopWatch
// ---
// summary: Stop an issue's existing stopwatch.
// 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: index
// in: path
// description: index of the issue to stop the stopwatch on
// type: integer
// format: int64
// required: true
// responses:
// "201":
// "$ref": "#/responses/empty"
// "403":
// description: Not repo writer, user does not have rights to toggle stopwatch
// "404":
2019-12-20 20:07:12 +03:00
// "$ref": "#/responses/notFound"
2019-12-12 07:23:05 +03:00
// "409":
// description: Cannot stop a non existent stopwatch
2019-12-20 20:07:12 +03:00
2019-12-12 07:23:05 +03:00
issue , err := prepareIssueStopwatch ( ctx , true )
if err != nil {
return
}
if err := models . CreateOrStopIssueStopwatch ( ctx . User , issue ) ; err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "CreateOrStopIssueStopwatch" , err )
2019-12-12 07:23:05 +03:00
return
}
2019-12-20 20:07:12 +03:00
ctx . Status ( http . StatusCreated )
2019-12-12 07:23:05 +03:00
}
// DeleteIssueStopwatch delete a specific stopwatch
func DeleteIssueStopwatch ( ctx * context . APIContext ) {
// swagger:operation DELETE /repos/{owner}/{repo}/issues/{index}/stopwatch/delete issue issueDeleteStopWatch
// ---
// summary: Delete an issue's existing stopwatch.
// 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: index
// in: path
// description: index of the issue to stop the stopwatch on
// type: integer
// format: int64
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
// "403":
// description: Not repo writer, user does not have rights to toggle stopwatch
// "404":
2019-12-20 20:07:12 +03:00
// "$ref": "#/responses/notFound"
2019-12-12 07:23:05 +03:00
// "409":
// description: Cannot cancel a non existent stopwatch
2019-12-20 20:07:12 +03:00
2019-12-12 07:23:05 +03:00
issue , err := prepareIssueStopwatch ( ctx , true )
if err != nil {
return
}
if err := models . CancelStopwatch ( ctx . User , issue ) ; err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "CancelStopwatch" , err )
2019-12-12 07:23:05 +03:00
return
}
2019-12-20 20:07:12 +03:00
ctx . Status ( http . StatusNoContent )
2019-12-12 07:23:05 +03:00
}
func prepareIssueStopwatch ( ctx * context . APIContext , shouldExist bool ) ( * models . Issue , error ) {
issue , err := models . GetIssueByIndex ( ctx . Repo . Repository . ID , ctx . ParamsInt64 ( ":index" ) )
if err != nil {
if models . IsErrIssueNotExist ( err ) {
ctx . NotFound ( )
} else {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetIssueByIndex" , err )
2019-12-12 07:23:05 +03:00
}
return nil , err
}
2020-01-20 15:00:32 +03:00
if ! ctx . Repo . CanWriteIssuesOrPulls ( issue . IsPull ) {
2019-12-20 20:07:12 +03:00
ctx . Status ( http . StatusForbidden )
2020-03-08 20:46:24 +03:00
return nil , errors . New ( "Unable to write to PRs" )
2019-12-12 07:23:05 +03:00
}
if ! ctx . Repo . CanUseTimetracker ( issue , ctx . User ) {
2019-12-20 20:07:12 +03:00
ctx . Status ( http . StatusForbidden )
2020-03-08 20:46:24 +03:00
return nil , errors . New ( "Cannot use time tracker" )
2019-12-12 07:23:05 +03:00
}
if models . StopwatchExists ( ctx . User . ID , issue . ID ) != shouldExist {
if shouldExist {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusConflict , "StopwatchExists" , "cannot stop/cancel a non existent stopwatch" )
2020-03-08 20:46:24 +03:00
err = errors . New ( "cannot stop/cancel a non existent stopwatch" )
2019-12-12 07:23:05 +03:00
} else {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusConflict , "StopwatchExists" , "cannot start a stopwatch again if it already exists" )
2020-03-08 20:46:24 +03:00
err = errors . New ( "cannot start a stopwatch again if it already exists" )
2019-12-12 07:23:05 +03:00
}
return nil , err
}
return issue , nil
}
// GetStopwatches get all stopwatches
func GetStopwatches ( ctx * context . APIContext ) {
// swagger:operation GET /user/stopwatches user userGetStopWatches
// ---
// summary: Get list of all existing stopwatches
2020-01-24 22:00:29 +03:00
// parameters:
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
2020-06-09 07:57:38 +03:00
// description: page size of results
2020-01-24 22:00:29 +03:00
// type: integer
2019-12-12 07:23:05 +03:00
// consumes:
// - application/json
// produces:
// - application/json
// responses:
// "200":
// "$ref": "#/responses/StopWatchList"
2020-01-24 22:00:29 +03:00
sws , err := models . GetUserStopwatches ( ctx . User . ID , utils . GetListOptions ( ctx ) )
2019-12-12 07:23:05 +03:00
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "GetUserStopwatches" , err )
2019-12-12 07:23:05 +03:00
return
}
apiSWs , err := sws . APIFormat ( )
if err != nil {
2019-12-20 20:07:12 +03:00
ctx . Error ( http . StatusInternalServerError , "APIFormat" , err )
2019-12-12 07:23:05 +03:00
return
}
2019-12-20 20:07:12 +03:00
ctx . JSON ( http . StatusOK , apiSWs )
2019-12-12 07:23:05 +03:00
}