@@ -5,61 +5,35 @@ package cmd
55import (
66 "encoding/json"
77 "fmt"
8- "github.com/spf13/cobra"
9- "io"
10- "net/http"
118 "strings"
12- "time"
13- )
14-
15- func formatText (text string ) string {
16- text = strings .TrimSpace (text )
17-
18- text = strings .Join (strings .Fields (text ), " " )
199
20- text = strings .Map (func (r rune ) rune {
21- if r < 32 || r > 126 {
22- return - 1
23- }
24- return r
25- }, text )
10+ "github.com/prime-run/go-typer/types"
11+ "github.com/prime-run/go-typer/utils"
12+ "github.com/spf13/cobra"
13+ )
2614
27- return text
28- }
15+ const (
16+ ModeDefault types.Mode = "default" // default mode
17+ ModeWords types.Mode = "words" // word mode
18+ ModeSentences types.Mode = "sentences" // sentence mode
2919
30- func formatForGameMode (text string , mode string ) string {
31- text = formatText (text )
20+ zenQuotesAPIURL = "https://zenquotes.io/api/random" // ZenQuotes API URL
21+ bibleAPIURL = "https://bible-api.com/john+3:16" // Bible API URL
22+ )
3223
33- switch mode {
34- case "words" :
35- words := strings .Fields (text )
36- return strings .Join (words , "\n " )
37- case "sentences" :
38- text = strings .ReplaceAll (text , "." , ".\n " )
39- text = strings .ReplaceAll (text , "!" , "!\n " )
40- text = strings .ReplaceAll (text , "?" , "?\n " )
41- lines := strings .Split (text , "\n " )
42- var cleanLines []string
43- for _ , line := range lines {
44- if clean := strings .TrimSpace (line ); clean != "" {
45- cleanLines = append (cleanLines , clean )
46- }
47- }
48- return strings .Join (cleanLines , "\n " )
49- default :
50- return text
51- }
24+ func init () {
25+ rootCmd .AddCommand (fetchCmd )
5226}
5327
5428var fetchCmd = & cobra.Command {
5529 Use : "fetch" ,
5630 Short : "Test text fetching from APIs" ,
5731 Run : func (cmd * cobra.Command , args []string ) {
58- modes := []string { "default" , "words" , "sentences" }
32+ modes := []types. Mode { ModeDefault , ModeWords , ModeSentences }
5933
6034 fmt .Println ("Trying ZenQuotes API..." )
61- zenQuotes := & TextSource {
62- URL : "https://zenquotes.io/api/random" ,
35+ zenQuotes := & types. TextSource {
36+ URL : zenQuotesAPIURL ,
6337 Parser : func (body []byte ) (string , error ) {
6438 var result []struct {
6539 Quote string `json:"q"`
@@ -72,11 +46,11 @@ var fetchCmd = &cobra.Command{
7246 return "" , fmt .Errorf ("no quotes found in response" )
7347 }
7448
75- quote := formatText (result [0 ].Quote )
76- author := formatText (result [0 ].Author )
49+ quote := utils . FormatText (result [0 ].Quote )
50+ author := utils . FormatText (result [0 ].Author )
7751
7852 formattedQuote := quote
79- if ! strings . HasSuffix (quote , "." ) && ! strings . HasSuffix ( quote , "!" ) && ! strings . HasSuffix ( quote , "?" ) {
53+ if utils . HasPonctuationSuffix (quote ) {
8054 formattedQuote += "."
8155 }
8256 return fmt .Sprintf ("%s - %s" , formattedQuote , author ), nil
@@ -88,27 +62,23 @@ var fetchCmd = &cobra.Command{
8862 fmt .Printf ("\n ZenQuotes API success:\n " )
8963 for _ , mode := range modes {
9064 formatted := formatForGameMode (text , mode )
91- fmt .Printf ("\n Mode: %s\n " , mode )
92- fmt .Printf ("Text:\n %s\n " , formatted )
93- fmt .Printf ("Character count: %d\n " , len (formatted ))
94- fmt .Printf ("Line count: %d\n " , len (strings .Split (formatted , "\n " )))
65+ utils .PrintTextStats (mode , formatted )
9566 }
9667 }
9768
9869 fmt .Println ("\n Trying Bible API..." )
99- bible := & TextSource {
100- URL : "https://bible-api.com/john+3:16" ,
70+ bible := & types. TextSource {
71+ URL : bibleAPIURL ,
10172 Parser : func (body []byte ) (string , error ) {
10273 var result struct {
103- Text string `json:"text"`
104- Reference string `json:"reference"`
74+ Text string `json:"text"`
10575 }
10676 if err := json .Unmarshal (body , & result ); err != nil {
10777 return "" , fmt .Errorf ("failed to parse JSON: %w" , err )
10878 }
10979
110- verse := formatText (result .Text )
111- // WARN:don't include the reference for typing practice
80+ verse := utils . FormatText (result .Text )
81+ // ! WARN: don't include the reference for typing practice
11282 return verse , nil
11383 },
11484 }
@@ -118,47 +88,44 @@ var fetchCmd = &cobra.Command{
11888 fmt .Printf ("\n Bible API success:\n " )
11989 for _ , mode := range modes {
12090 formatted := formatForGameMode (text , mode )
121- fmt .Printf ("\n Mode: %s\n " , mode )
122- fmt .Printf ("Text:\n %s\n " , formatted )
123- fmt .Printf ("Character count: %d\n " , len (formatted ))
124- fmt .Printf ("Line count: %d\n " , len (strings .Split (formatted , "\n " )))
91+ utils .PrintTextStats (mode , formatted )
12592 }
12693 }
12794 },
12895}
12996
130- type TextSource struct {
131- URL string
132- Parser func ([]byte ) (string , error )
133- }
134-
135- func (s * TextSource ) FetchText () (string , error ) {
136- client := & http.Client {
137- Timeout : 10 * time .Second ,
138- }
97+ // formatForGameMode formats the text based on the specified game mode.
98+ func formatForGameMode (text string , mode types.Mode ) string {
99+ text = utils .FormatText (text )
139100
140- fmt .Printf ("Fetching from URL: %s\n " , s .URL )
141- resp , err := client .Get (s .URL )
142- if err != nil {
143- return "" , fmt .Errorf ("failed to fetch: %w" , err )
101+ switch mode {
102+ case ModeWords :
103+ return formatForWords (text )
104+ case ModeSentences :
105+ return formatForSentences (text )
106+ default :
107+ return text
144108 }
145- defer resp . Body . Close ()
109+ }
146110
147- if resp .StatusCode != http .StatusOK {
148- return "" , fmt .Errorf ("API returned status %d" , resp .StatusCode )
149- }
111+ // formatForWords formats the text for word mode by splitting it into lines based on spaces.
112+ // Each word is placed on a new line.
113+ func formatForWords (text string ) string {
114+ words := strings .Fields (text )
115+ return strings .Join (words , "\n " )
116+ }
150117
151- body , err := io .ReadAll (resp .Body )
152- if err != nil {
153- return "" , fmt .Errorf ("failed to read response: %w" , err )
154- }
118+ // formatForSentences formats the text for sentence mode by splitting it into lines based on punctuation.
119+ func formatForSentences (text string ) string {
120+ text = strings .ReplaceAll (text , "." , ".\n " )
121+ text = strings .ReplaceAll (text , "!" , "!\n " )
122+ text = strings .ReplaceAll (text , "?" , "?\n " )
155123
156- if s .Parser != nil {
157- return s .Parser (body )
124+ var cleanLines []string
125+ for line := range strings .Lines (text ) {
126+ if clean := strings .TrimSpace (line ); clean != "" {
127+ cleanLines = append (cleanLines , clean )
128+ }
158129 }
159- return string (body ), nil
160- }
161-
162- func init () {
163- rootCmd .AddCommand (fetchCmd )
130+ return strings .Join (cleanLines , "\n " )
164131}
0 commit comments