Skip to content

Commit 5b2b513

Browse files
🏗️Restructuring Code
🚧 [ui/profile.go] Pretty print output
1 parent 680771c commit 5b2b513

File tree

13 files changed

+287
-77
lines changed

13 files changed

+287
-77
lines changed

cmd/cmd_login.go

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,20 @@
11
package cmd
22

33
import (
4-
"errors"
5-
"fmt"
6-
"os"
7-
"strings"
8-
9-
"github.com/CosmicPredator/chibi/internal"
10-
"github.com/charmbracelet/huh"
4+
"github.com/CosmicPredator/chibi/internal/ui"
5+
"github.com/CosmicPredator/chibi/internal/viewmodel"
116
"github.com/spf13/cobra"
127
)
138

14-
func handleLoginCommand() {
15-
var code string
16-
17-
authRequest := internal.NewAuthRequest()
18-
fmt.Printf("Open the below link in browser to login with anilist: \n\n")
19-
20-
fmt.Print(
21-
OTHER_MESSAGE_TEMPLATE.Render(authRequest.GetAuthURL()),
22-
)
23-
24-
fmt.Print("\n\n")
25-
26-
huh.NewText().
27-
Title("Paste your token here:").
28-
CharLimit(2000).
29-
Value(&code).
30-
Validate(func(s string) error {
31-
if s == "" {
32-
return errors.New("please provide a valid token")
33-
}
34-
return nil
35-
}).
36-
Run()
37-
38-
if code == "" {
39-
fmt.Println(
40-
ERROR_MESSAGE_TEMPLATE.Render("please provide a valid token"),
41-
)
42-
os.Exit(0)
43-
}
44-
45-
err := authRequest.Login(strings.TrimSpace(code))
9+
func handleLoginCmd(cmd *cobra.Command, args []string) {
10+
err := viewmodel.HandleLogin()
4611
if err != nil {
47-
ErrorMessage(err.Error())
12+
ui.ErrorText(err)
4813
}
49-
fmt.Println("Login Successful")
5014
}
5115

5216
var loginCmd = &cobra.Command{
5317
Use: "login",
5418
Short: "Login with anilist",
55-
Run: func(cmd *cobra.Command, args []string) {
56-
handleLoginCommand()
57-
},
19+
Run: handleLoginCmd,
5820
}

cmd/cmd_profile.go

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,40 @@
11
package cmd
22

33
import (
4-
"fmt"
5-
"strconv"
6-
7-
"github.com/CosmicPredator/chibi/internal"
8-
"github.com/charmbracelet/lipgloss"
4+
"github.com/CosmicPredator/chibi/internal/ui"
5+
"github.com/CosmicPredator/chibi/internal/viewmodel"
96
"github.com/spf13/cobra"
107
)
118

12-
func getUserProfile() {
13-
CheckIfTokenExists()
14-
profile := internal.NewProfile()
15-
err := profile.Get()
16-
if err != nil {
17-
ErrorMessage(err.Error())
18-
}
9+
// func getUserProfile() {
10+
// CheckIfTokenExists()
11+
// profile := internal.NewProfile()
12+
// err := profile.Get()
13+
// if err != nil {
14+
// ErrorMessage(err.Error())
15+
// }
1916

20-
keyStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#FF79C6"))
21-
valueStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#8BE9FD"))
17+
// keyStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#FF79C6"))
18+
// valueStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#8BE9FD"))
2219

23-
fmt.Printf("%-20s : %s\n", keyStyle.Render("ID"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Id)))
24-
fmt.Printf("%-20s : %s\n", keyStyle.Render("Name"), valueStyle.Render(profile.Data.Viewer.Name))
25-
fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Anime"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Statistics.Anime.Count)))
26-
fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Manga"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Statistics.Manga.Count)))
27-
fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Days Watched"), valueStyle.Render(fmt.Sprintf("%.2f", float32(profile.Data.Viewer.Statistics.Anime.MinutesWatched)/1440)))
28-
fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Chapters Read"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Statistics.Manga.ChaptersRead)))
29-
fmt.Printf("%-20s : %s\n", keyStyle.Render("URL"), valueStyle.Render(profile.Data.Viewer.SiteUrl))
20+
// fmt.Printf("%-20s : %s\n", keyStyle.Render("ID"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Id)))
21+
// fmt.Printf("%-20s : %s\n", keyStyle.Render("Name"), valueStyle.Render(profile.Data.Viewer.Name))
22+
// fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Anime"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Statistics.Anime.Count)))
23+
// fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Manga"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Statistics.Manga.Count)))
24+
// fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Days Watched"), valueStyle.Render(fmt.Sprintf("%.2f", float32(profile.Data.Viewer.Statistics.Anime.MinutesWatched)/1440)))
25+
// fmt.Printf("%-20s : %s\n", keyStyle.Render("Total Chapters Read"), valueStyle.Render(strconv.Itoa(profile.Data.Viewer.Statistics.Manga.ChaptersRead)))
26+
// fmt.Printf("%-20s : %s\n", keyStyle.Render("URL"), valueStyle.Render(profile.Data.Viewer.SiteUrl))
27+
// }
28+
29+
func handleProfile(cmd *cobra.Command, args []string) {
30+
err := viewmodel.HandleProfile()
31+
if err != nil {
32+
ui.ErrorText(err)
33+
}
3034
}
3135

3236
var profileCmd = &cobra.Command{
3337
Use: "profile",
3438
Short: "Get's your AniList profile (requires login)",
35-
Run: func(cmd *cobra.Command, args []string) {
36-
getUserProfile()
37-
},
39+
Run: handleProfile,
3840
}

cmd/cmd_root.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ var rootCmd = &cobra.Command{
1919
cmd.Help()
2020
}
2121
},
22-
}
23-
24-
func init() {
25-
rootCmd.Flags().BoolVarP(&isVersionCmd, "version", "v", false, "Prints the version of the app")
22+
Version: appVersion,
2623
}
2724

2825
func Execute(version string) {

internal/api/anilist.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99

1010
"github.com/CosmicPredator/chibi/internal/api/responses"
11+
"github.com/CosmicPredator/chibi/types"
1112
)
1213

1314
// Base URL is not gonna get changed for a while.
@@ -32,7 +33,15 @@ func queryAnilist(query string, variables map[string]any) ([]byte, error) {
3233
if err != nil {
3334
return nil, err
3435
}
36+
37+
tokenConfig := types.NewTokenConfig()
38+
err = tokenConfig.ReadFromJsonFile()
39+
if err != nil {
40+
return nil, err
41+
}
42+
3543
req.Header.Set("Content-Type", "application/json")
44+
req.Header.Set("Authorization", "Bearer " + tokenConfig.AccessToken)
3645

3746
httpClient := &http.Client{}
3847
resp, err := httpClient.Do(req)
@@ -98,5 +107,22 @@ func GetMediaList(userId int, mediaType string, mediaStatus string) (*responses.
98107
return nil, err
99108
}
100109

110+
return &responseStruct, nil
111+
}
112+
113+
// Herlper function to get details about the
114+
// logged user
115+
func GetUserProfile() (*responses.Profile, error) {
116+
response, err := queryAnilist(viewerQuery, nil)
117+
if err != nil {
118+
return nil, err
119+
}
120+
121+
var responseStruct responses.Profile
122+
err = json.Unmarshal(response, &responseStruct)
123+
if err != nil {
124+
return nil, err
125+
}
126+
101127
return &responseStruct, nil
102128
}

internal/api/queries.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,22 @@ var mediaListQuery = `query($userId: Int, $type: MediaType, $status: [MediaListS
3333
}
3434
}
3535
}
36+
}`
37+
38+
var viewerQuery = `query {
39+
Viewer {
40+
id
41+
name
42+
statistics {
43+
anime {
44+
count
45+
minutesWatched
46+
}
47+
manga {
48+
count
49+
chaptersRead
50+
}
51+
}
52+
siteUrl
53+
}
3654
}`

internal/auth.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ import (
1313
type AuthRequest struct{}
1414

1515
func (a AuthRequest) GetAuthURL() string {
16-
return fmt.Sprintf(
17-
"https://anilist.co/api/v2/oauth/authorize?client_id=%v&response_type=token",
18-
CLIENT_ID,
19-
)
16+
return AUTH_URL
2017
}
2118

2219
func (a AuthRequest) Login(authCode string) error {

internal/constants.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
package internal
22

3-
const CLIENT_ID = "4593"
3+
const AUTH_URL = "https://anilist.co/api/v2/oauth/authorize?client_id=4593&response_type=token"
4+
var ACCESS_TOKEN = ""

internal/ui/login.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package ui
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/charmbracelet/huh"
9+
)
10+
11+
type LoginUI struct {
12+
loginURL string
13+
token string
14+
}
15+
16+
// setter only method on loginURL field
17+
func (l *LoginUI) SetLoginURL(loginUrl string) {
18+
l.loginURL = loginUrl
19+
}
20+
21+
// getter only method on token field
22+
func (l LoginUI) GetAuthToken() string {
23+
return l.token
24+
}
25+
26+
func (l *LoginUI) Render() error {
27+
// display login url
28+
var sb strings.Builder
29+
sb.WriteString("Open the below link in browser to login with anilist:")
30+
sb.WriteString("\n")
31+
sb.WriteString(HighlightedText(l.loginURL))
32+
sb.WriteString("\n\n")
33+
fmt.Print(sb.String())
34+
35+
// display token entry form
36+
err := huh.NewText().
37+
Title("Paste your token here").
38+
Value(&l.token).
39+
CharLimit(2000).
40+
Validate(func(s string) error {
41+
if s == "" {
42+
return errors.New("please provide a valid token")
43+
}
44+
return nil
45+
}).
46+
Run()
47+
return err
48+
}

internal/ui/profile.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package ui
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
7+
//"github.com/charmbracelet/lipgloss"
8+
)
9+
10+
type ProfileUI struct {
11+
Id int
12+
Name string
13+
TotalAnime int
14+
TotalManga int
15+
MinutesWatched int
16+
ChaptersRead int
17+
SiteUrl string
18+
}
19+
20+
type KV struct {
21+
Key string
22+
Value string
23+
}
24+
25+
func (p *ProfileUI) Render() error {
26+
daysWatched := float32(p.MinutesWatched)/1440
27+
28+
var dataSlice = []KV{
29+
{ "ID", strconv.Itoa(p.Id) },
30+
{ "Name", p.Name },
31+
{ "Total Anime", strconv.Itoa(p.TotalAnime) },
32+
{ "Total Manga", strconv.Itoa(p.TotalManga) },
33+
{ "Total Days Watched", fmt.Sprintf("%.2f", daysWatched) },
34+
{ "Total Chapters Read", strconv.Itoa(p.ChaptersRead) },
35+
{ "Site URL", p.SiteUrl },
36+
}
37+
38+
maxKeyLen := 0
39+
for _, kv := range dataSlice {
40+
if len(kv.Key) > maxKeyLen {
41+
maxKeyLen = len(kv.Key)
42+
}
43+
}
44+
45+
//keyStyle := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("#FF79C6"))
46+
//valueStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#8BE9FD"))
47+
48+
for _, kv := range dataSlice {
49+
fmt.Printf("%-*s : %s\n", maxKeyLen, kv.Key, kv.Value)
50+
}
51+
52+
return nil
53+
}

internal/ui/renderable.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package ui
2+
3+
// common interface for renderable objects
4+
type IRenderable interface {
5+
Render() error
6+
}

0 commit comments

Comments
 (0)