From a3eb6c6e324ca3892bb3f9f983756e716c4a41c5 Mon Sep 17 00:00:00 2001 From: trafficlunar Date: Sat, 3 May 2025 16:09:46 +0100 Subject: [PATCH] feat: github projects route --- .env.example | 4 +++ internal/handler/github.go | 12 ++++++++ internal/model/github.go | 16 ++++++++++ internal/server/router.go | 1 + internal/service/github.go | 62 ++++++++++++++++++++++++++++++++++++++ internal/worker/github.go | 19 ++++++++++++ internal/worker/worker.go | 1 + 7 files changed, 115 insertions(+) create mode 100644 internal/handler/github.go create mode 100644 internal/model/github.go create mode 100644 internal/service/github.go create mode 100644 internal/worker/github.go diff --git a/.env.example b/.env.example index da8f2c2..7f7b90a 100644 --- a/.env.example +++ b/.env.example @@ -8,6 +8,10 @@ LASTFM_USERNAME="axolotlmaid" # API key for last.fm LASTFM_API_KEY="API_KEY_GOES_HERE" +# GitHub slugs split by comma (,) +GITHUB_PROJECTS="trafficlunar/options-profiles,trafficlunar/blockmatic" +# GitHub token +GITHUB_TOKEN="API_KEY_GOES_HERE" # The password for the computer WebSocket WEBSOCKET_PASSWORD="PASSWORD_GOES_HERE" \ No newline at end of file diff --git a/internal/handler/github.go b/internal/handler/github.go new file mode 100644 index 0000000..ee28ec0 --- /dev/null +++ b/internal/handler/github.go @@ -0,0 +1,12 @@ +package handler + +import ( + "api/internal/worker" + "encoding/json" + "net/http" +) + +func HandleGetProjects(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(worker.GitHubData) +} diff --git a/internal/model/github.go b/internal/model/github.go new file mode 100644 index 0000000..4cf3256 --- /dev/null +++ b/internal/model/github.go @@ -0,0 +1,16 @@ +package model + +type GitHubAPI struct { + Description string `json:"description"` + Stars uint32 `json:"stargazers_count"` + Language string `json:"language"` + Url string `json:"html_url"` +} + +type GitHubData struct { + Name string `json:"name"` + Description string `json:"description"` + Stars string `json:"stars"` + Language string `json:"language"` + Url string `json:"url"` +} diff --git a/internal/server/router.go b/internal/server/router.go index cae3e62..e6bf3c4 100644 --- a/internal/server/router.go +++ b/internal/server/router.go @@ -54,6 +54,7 @@ func NewRouter() { r.Get("/hit", handler.HandleGetHitCounter) r.With(httprate.LimitByRealIP(1, time.Hour)).Patch("/hit", handler.HandlePatchHitCounter) r.Get("/song", handler.HandleGetCurrentlyPlaying) + r.Get("/projects", handler.HandleGetProjects) r.Get("/computer", handler.HandleComputerGraphData) r.Get("/computer/ws", handler.HandleComputerWebSocket) diff --git a/internal/service/github.go b/internal/service/github.go new file mode 100644 index 0000000..1c16752 --- /dev/null +++ b/internal/service/github.go @@ -0,0 +1,62 @@ +package service + +import ( + "api/internal/model" + "encoding/json" + "fmt" + "io" + "log/slog" + "net/http" + "os" + "strings" +) + +func GetGitHubData() []model.GitHubData { + data := []model.GitHubData{} + + projects := strings.Split(os.Getenv("GITHUB_PROJECTS"), ",") + client := &http.Client{} + + // Go through every project specified in GITHUB_PROJECTS + for _, project := range projects { + url := fmt.Sprintf("https://api.github.com/repos/%s", project) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + slog.Error("Error creating request", slog.Any("error", err)) + continue + } + + // Add authorization header + req.Header.Set("Authorization", "token "+os.Getenv("GITHUB_TOKEN")) + + res, err := client.Do(req) + if err != nil { + slog.Error("Error requesting GitHub API", slog.Any("error", err)) + continue + } + defer res.Body.Close() + + body, err := io.ReadAll(res.Body) + if err != nil { + slog.Error("Error reading body", slog.Any("error", err)) + continue + } + + var apiResponse model.GitHubAPI + err = json.Unmarshal(body, &apiResponse) + if err != nil { + slog.Error("Error unmarshalling JSON", slog.Any("error", err)) + continue + } + + data = append(data, model.GitHubData{ + Name: project, + Description: apiResponse.Description, + Stars: fmt.Sprint(apiResponse.Stars), + Language: apiResponse.Language, + Url: apiResponse.Url, + }) + } + + return data +} diff --git a/internal/worker/github.go b/internal/worker/github.go new file mode 100644 index 0000000..cc56954 --- /dev/null +++ b/internal/worker/github.go @@ -0,0 +1,19 @@ +package worker + +import ( + "api/internal/model" + "api/internal/service" + "log/slog" + "time" +) + +var GitHubData []model.GitHubData + +func StartGitHubWorker() { + slog.Info("Starting GitHub worker...") + GitHubData = service.GetGitHubData() + + for range time.Tick(24 * time.Hour) { + GitHubData = service.GetGitHubData() + } +} diff --git a/internal/worker/worker.go b/internal/worker/worker.go index ad959f7..232988a 100644 --- a/internal/worker/worker.go +++ b/internal/worker/worker.go @@ -3,5 +3,6 @@ package worker func StartWorkers() { go StartDataStoreWorker() go StartLastFMWorker() + go StartGitHubWorker() go StartComputerWorker() }