diff --git a/config.go b/config.go index d95d6a5..5fc56fc 100644 --- a/config.go +++ b/config.go @@ -9,14 +9,14 @@ import ( // Server holds information about a Gitea server. type Server struct { servername string - url string - username string - token string + url string + username string + token string } // Configuration holds data retrieved from a Lua script. type Configuration struct { - servers []Server + servers []*Server } // parseText parses a text value from the configuration file. @@ -45,7 +45,7 @@ func parseServerFromTable(L *lua.LState, table lua.LValue) (Server, error) { if err := getStringFromTable(L, table, "url", &server.url); err != nil { return server, err } - + return server, nil } @@ -60,10 +60,10 @@ func (config *Configuration) Parse(fname string) error { for i := 1; i <= L.ObjLen(table); i++ { lserver := L.GetTable(table, lua.LNumber(i)) if server, err := parseServerFromTable(L, lserver); err == nil { - config.servers = append(config.servers, server) + config.servers = append(config.servers, &server) } else { return err } - } + } return nil } diff --git a/feed.go b/feed.go new file mode 100644 index 0000000..4274986 --- /dev/null +++ b/feed.go @@ -0,0 +1,96 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" + + "code.gitea.io/sdk/gitea" +) + +// Activity stores an entry in a gitea user's activity feed. +type Activity struct { + act_user *gitea.User + act_user_id int64 + comment gitea.Comment + comment_id int64 + content string + created string + id int64 + is_private bool + op_type string + ref_name string + repo *gitea.Repository + repo_id int64 + user_id int64 +} + +// getActivityFeed returns the authenticated user's activity feed. +func getActivityFeed() []Activity { + feed := []Activity{} + for _, server := range config.servers { + client := Servers[server.servername] + resp, err := http.Get(fmt.Sprintf("%s/api/v1/users/%s/activities/feeds?limit=10&page=1", + server.url, + server.username, + )) + if err != nil { + println("Failed to make HTTP request") + continue + } + + defer resp.Body.Close() + var data []map[string]interface{} + err = json.NewDecoder(resp.Body).Decode(&data) + if err != nil { + 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)) + continue + } + // repo, _, err := client.GetRepo( + // obj["repo"]. + // (map[string]interface{})["name"].(string), + // obj["repo"]. + // (map[string]interface{})["owner"]. + // (map[string]interface{})["login"].(string), + // ) + // if err != nil { + // fmt.Println("Failed to get repository: "+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), + OriginalAuthorID: int64(raw_comment["original_author_id"].(float64)), + } + } + feed = append(feed, Activity{ + // repo: repo, + 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)), + }) + } + } + return feed +} diff --git a/main.go b/main.go index f9b961b..83c6400 100644 --- a/main.go +++ b/main.go @@ -10,11 +10,13 @@ import ( ) var config Configuration -var Clients map[string]*gitea.Client +var Servers map[string]*gitea.Client func main() { parser := argparse.NewParser("gitivity", "Command line tool to get Gitea statistics") Times := parser.NewCommand("times", "Get a user's tracked times.") + Summary := parser.NewCommand("summary", "Display a summary of a user's activity.") + Feed := parser.NewCommand("feed", "Display the user's activity feed.") config_path := parser.String("c", "config", &argparse.Options{Required: false, Help: "Configuration file", Default: "./config.lua"}) server_option := parser.String("s", "server", &argparse.Options{Required: false, Help: "Specific server to use"}) @@ -24,8 +26,8 @@ func main() { return } - Clients = make(map[string]*gitea.Client) config = Configuration{} + Servers = make(map[string]*gitea.Client) if err := config.Parse(*config_path); err != nil { panic("Failed to parse configuration file") } @@ -42,14 +44,18 @@ func main() { fmt.Printf("Failed to create Gitea client! (%s)\n", err) os.Exit(1) } - Clients[server.servername] = client + Servers[server.servername] = client } - if len(Clients) == 0 { + if len(Servers) == 0 { println("No servers configured / specified") os.Exit(0) } if Times.Happened() { times() + } else if Summary.Happened() { + summary() + } else if Feed.Happened() { + //feed() } } diff --git a/styles.go b/styles.go index 37bfc90..7d1dbfe 100644 --- a/styles.go +++ b/styles.go @@ -9,6 +9,9 @@ type Colors struct { overlay []lipgloss.Color } +type Styles struct { +} + var colors = Colors{ green: lipgloss.Color("#a6da95"), text: lipgloss.Color("#cad3f5"), diff --git a/summary.go b/summary.go new file mode 100644 index 0000000..eff2c9f --- /dev/null +++ b/summary.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" + "time" + + "code.gitea.io/sdk/gitea" + tea "github.com/charmbracelet/bubbletea" +) + +type summaryviewer struct { + times []gitea.TrackedTime + total_time time.Duration + quitting bool +} + +func (m summaryviewer) Init() tea.Cmd { + return nil +} + +func (m summaryviewer) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "q", "ctrl+c": + return m, tea.Quit + default: + return m, tea.Printf("You pressed: %s", msg.String()) + } + } + return m, nil +} + +func (m summaryviewer) View() string { + s := "" + if !m.quitting { + s += "Showing statistics for user " + return s + } + return s +} + +func summary() { + p := tea.NewProgram(initialIndicator(("Fetching time logs..."))) + go func() { + if _, err := p.Run(); err != nil { + panic("An error occured.") + } + }() + + viewer := summaryviewer{} + since := time.Now().AddDate(0, 0, -14) + viewer.times = getTimeLogs(since, func(repo gitea.Repository, took time.Duration) { + p.Send(IndicatorInfo{ + info: fmt.Sprintf("%s / %s", repo.Owner.UserName, repo.Name), + duration: took, + }) + }) + + for _, t := range viewer.times { + viewer.total_time += time.Duration(t.Time * int64(time.Second)) + } + + p.Send(IndicatorInfo{info: "Done", quitting: true}) + p.RestoreTerminal() + p.Quit() + + program := tea.NewProgram(viewer) + if _, err := program.Run(); err != nil { + panic("An error occurred.") + } +} diff --git a/times.go b/times.go index 4d19d33..ec3e8eb 100644 --- a/times.go +++ b/times.go @@ -15,7 +15,7 @@ import ( // getTimeLogs gets every single time log possible. func getTimeLogs(since time.Time, on_process_repo func(repo gitea.Repository, took time.Duration)) []gitea.TrackedTime { var times []gitea.TrackedTime - for _, client := range Clients { + for _, client := range Servers { page := 1 user, _, err := client.GetMyUserInfo() if err != nil {