package gitea import ( "bytes" "encoding/json" "fmt" "net/http" "time" "gitea.yves-biener.de/yves-biener/gitwarrior/internal/diff" "gitea.yves-biener.de/yves-biener/gitwarrior/internal/taskwarrior" ) type Milestone struct { Id uint `json:"id"` Title string `json:"title"` Description string `json:"description"` State string `json:"state"` Open_issues uint `json:"open_issues"` Closed_issues uint `json:"closed_issues"` Created_at time.Time `json:"created_at"` Updated_at time.Time `json:"updated_at"` Due_on time.Time `json:"due_on"` Closed_at time.Time `json:"closed_at"` } func (milestone *Milestone) IntoTask(repository Repository) (task taskwarrior.Task) { task = taskwarrior.NewTask( milestone.Title, repository.Name, milestone.Id, taskwarrior.MILESTONE, ) task.Due = taskwarrior.GoTimeToTaskTime(milestone.Due_on) task.Entry = taskwarrior.GoTimeToTaskTime(milestone.Created_at) task.Modified = taskwarrior.GoTimeToTaskTime(milestone.Updated_at) task.AppendComment(milestone.Description, milestone.Updated_at) return } // TODO: implement merge for milestone tasks func (milestone *Milestone) MergeTask(task taskwarrior.Task) taskwarrior.Task { last_update := taskwarrior.TaskTimeToGoTime(task.Last_gitw_update) if milestone.Updated_at.After(last_update) { // there are changes we need to merge if taskwarrior.TaskTimeToGoTime(task.Modified).After(last_update) { // NOTE: this means that there are lacal modifications which are not yet pushed if task.Description != milestone.Title { task.Description = diff.Prompt(task.Description, milestone.Title, task.Description) } if task.Status == "completed" || milestone.State == "closed" { if !(task.Status == "completed" && milestone.State == "closed" || task.Status != "completed" && milestone.State != "closed") { task.Status = diff.Prompt(task.Status, milestone.State, task.Status) } } if len(task.Annotations) < 1 { task.AppendComment(milestone.Description, milestone.Created_at) } else { task.Annotations[0].Description = diff.Prompt(task.Annotations[0].Description, milestone.Description, task.Annotations[0].Description) task.Annotations[0].Entry = taskwarrior.GoTimeToTaskTime(time.Now().In(time.Local)) } } else { // NOTE: there are no modifications between the last received update and the current version, hence we just accept theirs fully task.Description = milestone.Title if milestone.State == "closed" { // otherwise do not update the value task.Status = "completed" task.End = taskwarrior.GoTimeToTaskTime(milestone.Closed_at) } if len(task.Annotations) == 1 { task.Annotations[0].Description = milestone.Description task.Annotations[0].Entry = taskwarrior.GoTimeToTaskTime(milestone.Updated_at) } else { task.AppendComment(milestone.Description, milestone.Updated_at) } } task.Last_gitw_update = taskwarrior.GoTimeToTaskTime(time.Now().In(time.Local)) } return task } func (gitea *Gitea) GetMilestones(repo Repository) ([]Milestone, error) { url := fmt.Sprintf("%s/repos/%s/milestones?state=all", gitea.Url(), repo.Full_name) response, err := http.Get(url) if err != nil { return nil, err } defer response.Body.Close() var data []Milestone decoder := json.NewDecoder(response.Body) // NOTE: remove this if I do not want to store everything from the json result in the struct decoder.DisallowUnknownFields() // remain if every field shall be extracted if err = decoder.Decode(&data); err != nil { return nil, err } return data, nil } func (gitea *Gitea) GetMilestone(repo Repository, id uint) (Milestone, error) { url := fmt.Sprintf("%s/repos/%s/milestones/%d", gitea.Url(), repo.Full_name, id) response, err := http.Get(url) var milestone Milestone if err != nil { return milestone, err } defer response.Body.Close() decoder := json.NewDecoder(response.Body) // NOTE: remove this if I do not want to store everything from the json result in the struct decoder.DisallowUnknownFields() // remain if every field shall be extracted if err = decoder.Decode(&milestone); err != nil { return milestone, err } return milestone, nil } func (gitea *Gitea) UpdateMilestone(repo Repository, milestone Milestone) error { url := fmt.Sprintf("%s/repos/%s/milestones/%d", gitea.Url(), repo.Full_name, milestone.Id) var payload map[string]interface{} payload["description"] = milestone.Description payload["due_on"] = milestone.Due_on payload["state"] = milestone.State payload["title"] = milestone.Title json, err := json.Marshal(&payload) if err != nil { return err } _, err = http.NewRequest(http.MethodPatch, url, bytes.NewBuffer(json)) if err != nil { return err } return nil } func (gitea *Gitea) NewMilestone(repo Repository, milestone Milestone) (Milestone, error) { url := fmt.Sprintf("%s/repos/%s/milestones", gitea.Url(), repo.Full_name) payload, err := json.Marshal(&map[string]interface{}{ "description": milestone.Description, "due_on": milestone.Due_on, "state": milestone.State, "title": milestone.Title, }) var res Milestone if err != nil { return res, err } response, err := http.Post(url, "application/json", bytes.NewBuffer(payload)) if err != nil { return res, err } defer response.Body.Close() decoder := json.NewDecoder(response.Body) // NOTE: remove this if I do not want to stare everything from the json result in the struct decoder.DisallowUnknownFields() // remain if every field shall be extracted if err = decoder.Decode(&res); err != nil { return res, err } return res, nil }