From 15ba984d7653944fb80da0e0a946981de70b30ff Mon Sep 17 00:00:00 2001 From: Noah Date: Sun, 7 Apr 2024 15:11:10 -0500 Subject: [PATCH] feat(config): Allow a server to be set as the "default" server (fix #17) --- config.go | 40 +++++++++++++++++++++++++++++++++++++++- feed.go | 53 +++++++++++++++++++++++++++-------------------------- main.go | 22 +++++++++++++++++----- times.go | 2 +- 4 files changed, 84 insertions(+), 33 deletions(-) diff --git a/config.go b/config.go index af34cc0..fad673d 100644 --- a/config.go +++ b/config.go @@ -2,6 +2,7 @@ package main import ( "errors" + "fmt" "github.com/yuin/gopher-lua" ) @@ -15,9 +16,22 @@ type Server struct { primary bool } +// Servers holds all of the server structures. +type Servers map[string]*Server + +// getPrimary gets the primary server contained in this map. Returns an error if no primary server is defined. +func (servers *Servers) getPrimary() (*Server, error) { + for _, s := range *servers { + if s.primary { + return s, nil + } + } + return &Server{}, errors.New("No primary server found.") +} + // Configuration holds data retrieved from a Lua script. type Configuration struct { - servers map[string]*Server + servers Servers } // getStringFromTable parses a text value from the configuration file. @@ -31,6 +45,17 @@ func getStringFromTable(L *lua.LState, lobj lua.LValue, key string, out *string) return nil } +// getBoolFromTable parses a boolean value from the configuration file. +func getBoolFromTable(L *lua.LState, lobj lua.LValue, key string, out *bool) error { + lv := L.GetTable(lobj, lua.LString(key)) + if val, ok := lv.(lua.LBool); ok { + *out = bool(val) + } else { + return errors.New(fmt.Sprintf("Failed to get configuration value '%s'", key)) + } + return nil +} + // parseServerFromTable parses a Lua table into a Server structure. func parseServerFromTable(L *lua.LState, table lua.LValue) (Server, error) { server := Server{} @@ -47,6 +72,13 @@ func parseServerFromTable(L *lua.LState, table lua.LValue) (Server, error) { return server, err } + lv := L.GetTable(table, lua.LString("primary")) + if val, ok := lv.(lua.LBool); ok { + server.primary = bool(val) + } else if _, ok := lv.(*lua.LNilType); !ok { + panic("Config error : " + server.servername + " : Primary is neither nil nor boolean") + } + return server, nil } @@ -59,9 +91,15 @@ func (config *Configuration) Parse(fname string) error { L.DoFile(fname) table := L.Get(-1) + found_primary := false for i := 1; i <= L.ObjLen(table); i++ { lserver := L.GetTable(table, lua.LNumber(i)) if server, err := parseServerFromTable(L, lserver); err == nil { + if !found_primary && server.primary { + found_primary = true + } else if server.primary { + panic("Config error : " + server.servername + " : Cannot have multiple primary servers!") + } config.servers[server.servername] = &server } else { return err diff --git a/feed.go b/feed.go index 2145498..a9ff4b3 100644 --- a/feed.go +++ b/feed.go @@ -34,7 +34,7 @@ type Activity struct { func getActivityFeed() []Activity { feed := []Activity{} for _, server := range config.servers { - client := Servers[server.servername] + client := servers[server.servername] resp, err := http.Get(fmt.Sprintf("%s/api/v1/users/%s/activities/feeds?limit=15&page=1", server.url, server.username, @@ -48,41 +48,41 @@ func getActivityFeed() []Activity { var data []map[string]interface{} err = json.NewDecoder(resp.Body).Decode(&data) if err != nil { - fmt.Println("Error decoding JSON: "+fmt.Sprint(err)) + fmt.Println("Error decoding JSON: " + fmt.Sprint(err)) continue } for _, obj := range data { act_user, _, err := client.GetUserInfo(obj["act_user"].(map[string]interface{})["login"].(string)) if err != nil { - fmt.Println("Error getting user: "+fmt.Sprint(err)) + fmt.Println("Error getting user: " + fmt.Sprint(err)) continue } var comment gitea.Comment if obj["comment"] != nil { raw_comment := obj["comment"].(map[string]interface{}) comment = gitea.Comment{ - Body: raw_comment["body"].(string), - HTMLURL: raw_comment["html_url"].(string), - ID: int64(raw_comment["id"].(float64)), - IssueURL: raw_comment["issue_url"].(string), - OriginalAuthor: raw_comment["original_author"].(string), + Body: raw_comment["body"].(string), + HTMLURL: raw_comment["html_url"].(string), + ID: int64(raw_comment["id"].(float64)), + IssueURL: raw_comment["issue_url"].(string), + OriginalAuthor: raw_comment["original_author"].(string), OriginalAuthorID: int64(raw_comment["original_author_id"].(float64)), } } feed = append(feed, Activity{ // repo: repo, - act_user: act_user, + act_user: act_user, act_user_id: int64(obj["act_user_id"].(float64)), - comment: comment, - comment_id: int64(obj["comment_id"].(float64)), - content: obj["content"].(string), - created: obj["created"].(string), - id: int64(obj["id"].(float64)), - is_private: obj["is_private"].(bool), - op_type: obj["op_type"].(string), - ref_name: obj["ref_name"].(string), - repo_id: int64(obj["repo_id"].(float64)), - user_id: int64(obj["user_id"].(float64)), + comment: comment, + comment_id: int64(obj["comment_id"].(float64)), + content: obj["content"].(string), + created: obj["created"].(string), + id: int64(obj["id"].(float64)), + is_private: obj["is_private"].(bool), + op_type: obj["op_type"].(string), + ref_name: obj["ref_name"].(string), + repo_id: int64(obj["repo_id"].(float64)), + user_id: int64(obj["user_id"].(float64)), }) } } @@ -123,10 +123,10 @@ func newListKeyMap() *listKeyMap { } type feedviewer struct { - list list.Model - feed []Activity + list list.Model + feed []Activity appStyle lipgloss.Style - keys listKeyMap + keys listKeyMap } func (m feedviewer) Init() tea.Cmd { @@ -188,7 +188,7 @@ func (i item) Title() string { case "commit_repo": var data map[string]interface{} if err := json.NewDecoder(strings.NewReader(i.content)).Decode(&data); err != nil { - return "JSON decode error: "+fmt.Sprint(err) + return "JSON decode error: " + fmt.Sprint(err) } commits := data["Commits"].([]interface{}) commits_text := fmt.Sprintf("%d commit", len(commits)) @@ -210,15 +210,16 @@ func (i item) Description() string { case "commit_repo": var data map[string]interface{} if err := json.NewDecoder(strings.NewReader(i.content)).Decode(&data); err != nil { - return "JSON decode error: "+fmt.Sprint(err) + return "JSON decode error: " + fmt.Sprint(err) } s := "" commits := data["Commits"].([]interface{}) commit := commits[0].(map[string]interface{}) s += styles.text.Render(fmt.Sprintf("[%s] ", commit["Sha1"].(string)[0:10])) + - commit["Message"].(string) + commit["Message"].(string) return s - default: return "" + default: + return "" } } diff --git a/main.go b/main.go index 37af61d..fb5ba93 100644 --- a/main.go +++ b/main.go @@ -26,7 +26,7 @@ type Arguments struct { var arguments Arguments var config Configuration -var Servers map[string]*gitea.Client +var servers map[string]*gitea.Client func main() { parser := argparse.NewParser("gitivity", "Command line tool to get Gitea statistics") @@ -56,13 +56,24 @@ func main() { } config = Configuration{} - Servers = make(map[string]*gitea.Client) + servers = make(map[string]*gitea.Client) if err := config.Parse(*arguments.global.config_path); err != nil { panic("Failed to parse configuration file") } + // Specific server is used to ONLY use one of the available servers configured. + specific_server := "" + if *arguments.global.server != "" { // If a server was passed from CLI, + specific_server = *arguments.global.server // use that server. + } else { // Otherwise, + server, err := config.servers.getPrimary() // (Attempt to) get the primary server. + if err == nil { // If no error occured, we got the primary server. + specific_server = server.servername // Use the primary server + } + } + for _, server := range config.servers { - if *arguments.global.server != "" && strings.ToLower(server.servername) != strings.ToLower(*arguments.global.server) { + if specific_server != "" && strings.ToLower(server.servername) != strings.ToLower(specific_server) { continue } client_opts := []gitea.ClientOption{ @@ -73,9 +84,10 @@ func main() { fmt.Printf("Failed to create Gitea client! (%s)\n", err) os.Exit(1) } - Servers[server.servername] = client + servers[server.servername] = client } - if len(Servers) == 0 { + + if len(servers) == 0 { println("No servers configured / specified") os.Exit(0) } diff --git a/times.go b/times.go index baaf45e..ce1b9ef 100644 --- a/times.go +++ b/times.go @@ -114,7 +114,7 @@ type TrackedTime struct { // getTimeLogs gets every single time log possible. func getTimeLogs(since time.Time, on_process_repo func(repo gitea.Repository, took time.Duration)) []TrackedTime { var times []TrackedTime - for server_name, client := range Servers { + for server_name, client := range servers { page := 1 user, _, err := client.GetMyUserInfo() if err != nil {