-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[refactor]: separating Code for better readability (#5)
* combined all struct into one file * Configs will be fetch from this files only * http route handlers * adding routes to all the urls * refactoring * removing init and adding a func name and calling it in main func directly * fallback condition added --------- Co-authored-by: rmaurya <[email protected]>
- Loading branch information
1 parent
0cb761a
commit b5f7786
Showing
7 changed files
with
559 additions
and
514 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package common | ||
|
||
import "os" | ||
|
||
// Get port from environment variable or use default | ||
func GetPort() string { | ||
port := os.Getenv("PORT") | ||
if port == "" { | ||
port = "8080" | ||
} | ||
return port | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package common | ||
|
||
import "time" | ||
|
||
// ReleaseAsset represents a single asset in a release | ||
type ReleaseAsset struct { | ||
Name string `json:"name"` | ||
DownloadCount int `json:"download_count"` | ||
} | ||
|
||
// Release represents a GitHub release | ||
type Release struct { | ||
ID int `json:"id"` | ||
TagName string `json:"tag_name"` | ||
CreatedAt time.Time `json:"created_at"` | ||
Assets []ReleaseAsset `json:"assets"` | ||
} | ||
|
||
// ReleaseDownloadStats represents download statistics for a single release | ||
type ReleaseDownloadStats struct { | ||
TagName string `json:"tag_name"` | ||
CreatedAt time.Time `json:"created_at"` | ||
TotalDownloads int `json:"total_downloads"` | ||
Assets []AssetStats `json:"assets"` | ||
} | ||
|
||
// AssetStats represents download statistics for a single asset | ||
type AssetStats struct { | ||
Name string `json:"name"` | ||
DownloadCount int `json:"download_count"` | ||
} | ||
|
||
// DownloadStats represents download statistics for all releases | ||
type DownloadStats struct { | ||
RepoName string `json:"repo_name"` | ||
TotalDownloads int `json:"total_downloads"` | ||
Releases []ReleaseDownloadStats `json:"releases"` | ||
} | ||
|
||
type Config struct { | ||
GithubToken string | ||
} | ||
|
||
type Contributor struct { | ||
Login string `json:"login"` | ||
} | ||
|
||
type OrganizationStats struct { | ||
OrgName string `json:"org_name"` | ||
TotalRepos int `json:"total_repos"` | ||
TotalContributors int `json:"total_contributors"` | ||
} | ||
|
||
type StarHistory struct { | ||
RepoName string `json:"repo_name"` | ||
History []StarPoint `json:"history"` | ||
} | ||
|
||
// StarPoint represents stars at a specific point in time | ||
type StarPoint struct { | ||
Date time.Time `json:"date"` | ||
Stars int `json:"stars"` | ||
} | ||
|
||
// MultiRepoStarHistory represents star history for multiple repositories | ||
type MultiRepoStarHistory struct { | ||
Repositories []StarHistory `json:"repositories"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package handlers | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
|
||
cu "github.com/sonichigo/hg/common" | ||
) | ||
|
||
func HandleRepoStats(w http.ResponseWriter, r *http.Request) { | ||
if r.Method != http.MethodGet { | ||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) | ||
return | ||
} | ||
|
||
repoURL := r.URL.Query().Get("repo") | ||
if repoURL == "" { | ||
http.Error(w, "Repository URL is required", http.StatusBadRequest) | ||
return | ||
} | ||
|
||
owner, repo, err := extractRepoInfo(repoURL) | ||
if err != nil { | ||
http.Error(w, fmt.Sprintf("Invalid repository URL: %v", err), http.StatusBadRequest) | ||
return | ||
} | ||
|
||
// Make token optional | ||
var config *cu.Config | ||
authHeader := r.Header.Get("Authorization") | ||
if authHeader != "" { | ||
token := strings.TrimPrefix(authHeader, "Bearer ") | ||
token = strings.TrimSpace(token) | ||
config = &cu.Config{GithubToken: token} | ||
} | ||
|
||
releases, err := getAllReleases(owner, repo, config) | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
stats := calculateDownloadStats(releases) | ||
stats.RepoName = fmt.Sprintf("%s/%s", owner, repo) | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(stats) | ||
} | ||
func HandleStarHistory(w http.ResponseWriter, r *http.Request) { | ||
if r.Method != http.MethodGet { | ||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) | ||
return | ||
} | ||
|
||
// Get repositories from query parameter | ||
repos := r.URL.Query()["repo"] | ||
if len(repos) == 0 { | ||
http.Error(w, "At least one repository URL is required", http.StatusBadRequest) | ||
return | ||
} | ||
|
||
// Make token optional | ||
var config *cu.Config | ||
authHeader := r.Header.Get("Authorization") | ||
if authHeader != "" { | ||
token := strings.TrimPrefix(authHeader, "Bearer ") | ||
token = strings.TrimSpace(token) | ||
config = &cu.Config{GithubToken: token} | ||
} | ||
|
||
// Fetch star history for all repositories | ||
result := cu.MultiRepoStarHistory{ | ||
Repositories: make([]cu.StarHistory, 0, len(repos)), | ||
} | ||
|
||
for _, repoURL := range repos { | ||
owner, repo, err := extractRepoInfo(repoURL) | ||
if err != nil { | ||
http.Error(w, fmt.Sprintf("Invalid repository URL: %v", err), http.StatusBadRequest) | ||
return | ||
} | ||
|
||
history, err := getStarHistory(owner, repo, config) | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
result.Repositories = append(result.Repositories, *history) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} | ||
func HandleOrgContributors(w http.ResponseWriter, r *http.Request) { | ||
if r.Method != http.MethodGet { | ||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) | ||
return | ||
} | ||
|
||
org := r.URL.Query().Get("org") | ||
if org == "" { | ||
http.Error(w, "Organization name is required", http.StatusBadRequest) | ||
return | ||
} | ||
|
||
// Make token optional | ||
var config *cu.Config | ||
authHeader := r.Header.Get("Authorization") | ||
if authHeader != "" { | ||
token := strings.TrimPrefix(authHeader, "Bearer ") | ||
token = strings.TrimSpace(token) | ||
config = &cu.Config{GithubToken: token} | ||
} | ||
|
||
stats, err := getOrgContributors(org, config) | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(stats) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package handlers | ||
|
||
import "net/http" | ||
|
||
func ServerIndex(w http.ResponseWriter, r *http.Request) { | ||
if r.URL.Path == "/" { | ||
http.ServeFile(w, r, "./web/index.html") | ||
return | ||
} | ||
http.NotFound(w, r) | ||
} | ||
func ServerOrgPage(w http.ResponseWriter, r *http.Request) { | ||
if r.URL.Path == "/orgs" { | ||
http.ServeFile(w, r, "./web/org.html") | ||
return | ||
} | ||
} | ||
func ServerStartPage(w http.ResponseWriter, r *http.Request) { | ||
if r.URL.Path == "/starhistory" { | ||
http.ServeFile(w, r, "./web/stars.html") | ||
return | ||
} | ||
} |
Oops, something went wrong.