1// Copyright 2013 The go-github AUTHORS. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6package github
7
8import (
9	"context"
10	"fmt"
11)
12
13// StarredRepository is returned by ListStarred.
14type StarredRepository struct {
15	StarredAt  *Timestamp  `json:"starred_at,omitempty"`
16	Repository *Repository `json:"repo,omitempty"`
17}
18
19// Stargazer represents a user that has starred a repository.
20type Stargazer struct {
21	StarredAt *Timestamp `json:"starred_at,omitempty"`
22	User      *User      `json:"user,omitempty"`
23}
24
25// ListStargazers lists people who have starred the specified repo.
26//
27// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-stargazers
28func (s *ActivityService) ListStargazers(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Stargazer, *Response, error) {
29	u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo)
30	u, err := addOptions(u, opt)
31	if err != nil {
32		return nil, nil, err
33	}
34
35	req, err := s.client.NewRequest("GET", u, nil)
36	if err != nil {
37		return nil, nil, err
38	}
39
40	// TODO: remove custom Accept header when this API fully launches
41	req.Header.Set("Accept", mediaTypeStarringPreview)
42
43	var stargazers []*Stargazer
44	resp, err := s.client.Do(ctx, req, &stargazers)
45	if err != nil {
46		return nil, resp, err
47	}
48
49	return stargazers, resp, nil
50}
51
52// ActivityListStarredOptions specifies the optional parameters to the
53// ActivityService.ListStarred method.
54type ActivityListStarredOptions struct {
55	// How to sort the repository list. Possible values are: created, updated,
56	// pushed, full_name. Default is "full_name".
57	Sort string `url:"sort,omitempty"`
58
59	// Direction in which to sort repositories. Possible values are: asc, desc.
60	// Default is "asc" when sort is "full_name", otherwise default is "desc".
61	Direction string `url:"direction,omitempty"`
62
63	ListOptions
64}
65
66// ListStarred lists all the repos starred by a user. Passing the empty string
67// will list the starred repositories for the authenticated user.
68//
69// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-being-starred
70func (s *ActivityService) ListStarred(ctx context.Context, user string, opt *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) {
71	var u string
72	if user != "" {
73		u = fmt.Sprintf("users/%v/starred", user)
74	} else {
75		u = "user/starred"
76	}
77	u, err := addOptions(u, opt)
78	if err != nil {
79		return nil, nil, err
80	}
81
82	req, err := s.client.NewRequest("GET", u, nil)
83	if err != nil {
84		return nil, nil, err
85	}
86
87	// TODO: remove custom Accept header when this API fully launches
88	req.Header.Set("Accept", mediaTypeStarringPreview)
89
90	var repos []*StarredRepository
91	resp, err := s.client.Do(ctx, req, &repos)
92	if err != nil {
93		return nil, resp, err
94	}
95
96	return repos, resp, nil
97}
98
99// IsStarred checks if a repository is starred by authenticated user.
100//
101// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository
102func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bool, *Response, error) {
103	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
104	req, err := s.client.NewRequest("GET", u, nil)
105	if err != nil {
106		return false, nil, err
107	}
108	resp, err := s.client.Do(ctx, req, nil)
109	starred, err := parseBoolResponse(err)
110	return starred, resp, err
111}
112
113// Star a repository as the authenticated user.
114//
115// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository
116func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Response, error) {
117	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
118	req, err := s.client.NewRequest("PUT", u, nil)
119	if err != nil {
120		return nil, err
121	}
122	return s.client.Do(ctx, req, nil)
123}
124
125// Unstar a repository as the authenticated user.
126//
127// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository
128func (s *ActivityService) Unstar(ctx context.Context, owner, repo string) (*Response, error) {
129	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
130	req, err := s.client.NewRequest("DELETE", u, nil)
131	if err != nil {
132		return nil, err
133	}
134	return s.client.Do(ctx, req, nil)
135}
136