@@ -4,9 +4,10 @@ import (
44 "encoding/json"
55 "fmt"
66 "net/http"
7+ "strconv"
78 "strings"
89
9- cu "github.com/sonichigo/hg /common"
10+ cu "github.com/sonichigo/gitstats /common"
1011)
1112
1213func HandleRepoStats (w http.ResponseWriter , r * http.Request ) {
@@ -94,6 +95,7 @@ func HandleStarHistory(w http.ResponseWriter, r *http.Request) {
9495 w .Header ().Set ("Content-Type" , "application/json" )
9596 json .NewEncoder (w ).Encode (result )
9697}
98+
9799func HandleOrgContributors (w http.ResponseWriter , r * http.Request ) {
98100 if r .Method != http .MethodGet {
99101 http .Error (w , "Method not allowed" , http .StatusMethodNotAllowed )
@@ -124,3 +126,98 @@ func HandleOrgContributors(w http.ResponseWriter, r *http.Request) {
124126 w .Header ().Set ("Content-Type" , "application/json" )
125127 json .NewEncoder (w ).Encode (stats )
126128}
129+
130+ func HandleActiveContributors (w http.ResponseWriter , r * http.Request ) {
131+ if r .Method != http .MethodGet {
132+ http .Error (w , "Method not allowed" , http .StatusMethodNotAllowed )
133+ return
134+ }
135+
136+ repoURL := r .URL .Query ().Get ("repo" )
137+ orgName := r .URL .Query ().Get ("org" )
138+
139+ if orgName == "" && repoURL == "" {
140+ http .Error (w , "Either organization name or repository URL is required" , http .StatusBadRequest )
141+ return
142+ }
143+
144+ var config * cu.Config
145+
146+ // If repoURL is provided, handle single repository
147+ if repoURL != "" {
148+ owner , repo , err := extractRepoInfo (repoURL )
149+ if err != nil {
150+ http .Error (w , fmt .Sprintf ("Invalid repository URL: %v" , err ), http .StatusBadRequest )
151+ return
152+ }
153+ handleSingleRepo (w , owner , repo , config )
154+ return
155+ }
156+
157+ // Handle organization-wide contributors
158+ handleOrganization (w , orgName , config )
159+ }
160+
161+ func HandleStargazers (w http.ResponseWriter , r * http.Request ) {
162+ if r .Method != http .MethodGet {
163+ http .Error (w , "Method not allowed" , http .StatusMethodNotAllowed )
164+ return
165+ }
166+
167+ // Get query parameters
168+ owner := r .URL .Query ().Get ("owner" )
169+ repo := r .URL .Query ().Get ("repo" )
170+
171+ if owner == "" || repo == "" {
172+ http .Error (w , "Both owner and repository name are required" , http .StatusBadRequest )
173+ return
174+ }
175+
176+ // Parse page number
177+ page , err := strconv .Atoi (r .URL .Query ().Get ("page" ))
178+ if err != nil || page < 1 {
179+ page = 1
180+ }
181+
182+ // Get token from Authorization header
183+ var token string
184+ authHeader := r .Header .Get ("Authorization" )
185+ if authHeader != "" {
186+ token = strings .TrimPrefix (authHeader , "Bearer " )
187+ token = strings .TrimSpace (token )
188+ }
189+
190+ // Fetch stargazers
191+ stargazers , hasMore , total , err := fetchStargazers (owner , repo , token , page )
192+ if err != nil {
193+ http .Error (w , err .Error (), http .StatusInternalServerError )
194+ return
195+ }
196+
197+ // Prepare response data
198+ response := struct {
199+ Stargazers []cu.Stargazer `json:"stargazers"`
200+ HasMore bool `json:"has_more"`
201+ TotalCount int `json:"total_count"`
202+ CurrentPage int `json:"current_page"`
203+ NextPage int `json:"nextzz_page,omitempty"`
204+ }{
205+ Stargazers : stargazers ,
206+ HasMore : hasMore ,
207+ TotalCount : total ,
208+ CurrentPage : page ,
209+ }
210+
211+ if hasMore {
212+ response .NextPage = page + 1
213+ }
214+
215+ // Set response headers
216+ w .Header ().Set ("Content-Type" , "application/json" )
217+
218+ // Encode and send response
219+ if err := json .NewEncoder (w ).Encode (response ); err != nil {
220+ http .Error (w , "Error encoding response" , http .StatusInternalServerError )
221+ return
222+ }
223+ }
0 commit comments