···
"github.com/taciturnaxolotl/akami/styles"
16
+
"github.com/taciturnaxolotl/akami/utils"
"github.com/taciturnaxolotl/akami/wakatime"
···
Time: float64(time.Now().Unix()),
134
+
func getClientStuff(c *cobra.Command) (key string, url string, err error) {
135
+
configApiKey, _ := c.Flags().GetString("key")
136
+
configApiURL, _ := c.Flags().GetString("url")
138
+
// If either value is missing, try to load from config file
139
+
if configApiKey == "" || configApiURL == "" {
140
+
userDir, err := os.UserHomeDir()
142
+
errorTask(c, "Validating arguments")
143
+
return configApiKey, configApiURL, err
145
+
wakatimePath := filepath.Join(userDir, ".wakatime.cfg")
147
+
cfg, err := ini.Load(wakatimePath)
149
+
errorTask(c, "Validating arguments")
150
+
return configApiKey, configApiURL, errors.New("config file not found and you haven't passed all arguments")
153
+
settings, err := cfg.GetSection("settings")
155
+
errorTask(c, "Validating arguments")
156
+
return configApiKey, configApiURL, errors.New("no settings section in your config")
159
+
// Only load from config if not provided as parameter
160
+
if configApiKey == "" {
161
+
configApiKey = settings.Key("api_key").String()
162
+
if configApiKey == "" {
163
+
errorTask(c, "Validating arguments")
164
+
return configApiKey, configApiURL, errors.New("couldn't find an api_key in your config")
168
+
if configApiURL == "" {
169
+
configApiURL = settings.Key("api_url").String()
170
+
if configApiURL == "" {
171
+
errorTask(c, "Validating arguments")
172
+
return configApiKey, configApiURL, errors.New("couldn't find an api_url in your config")
177
+
return configApiKey, configApiURL, nil
func Doctor(c *cobra.Command, _ []string) error {
// Initialize a new context with task state
c.SetContext(context.WithValue(context.Background(), "taskState", &taskState{}))
···
completeTask(c, "Checking your coding stats for today")
228
-
// Convert seconds to a formatted time string (hours, minutes, seconds)
229
-
totalSeconds := duration.Data.GrandTotal.TotalSeconds
230
-
hours := totalSeconds / 3600
231
-
minutes := (totalSeconds % 3600) / 60
232
-
seconds := totalSeconds % 60
234
-
formattedTime := ""
236
-
formattedTime += fmt.Sprintf("%d hours, ", hours)
238
-
if minutes > 0 || hours > 0 {
239
-
formattedTime += fmt.Sprintf("%d minutes, ", minutes)
241
-
formattedTime += fmt.Sprintf("%d seconds", seconds)
243
-
c.Printf("Sweet!!! Looks like your hackatime is configured properly! Looks like you have coded today for %s\n\n", styles.Fancy.Render(formattedTime))
275
+
c.Printf("Sweet!!! Looks like your hackatime is configured properly! Looks like you have coded today for %s\n\n", styles.Fancy.Render(utils.PrettyPrintTime(duration.Data.GrandTotal.TotalSeconds)))
printTask(c, "Sending test heartbeat")
···
printTask(c, "Validating arguments")
265
-
configApiKey, _ := c.Flags().GetString("key")
266
-
configApiURL, _ := c.Flags().GetString("url")
268
-
// If either value is missing, try to load from config file
269
-
if configApiKey == "" || configApiURL == "" {
270
-
userDir, err := os.UserHomeDir()
272
-
errorTask(c, "Validating arguments")
275
-
wakatimePath := filepath.Join(userDir, ".wakatime.cfg")
277
-
cfg, err := ini.Load(wakatimePath)
279
-
errorTask(c, "Validating arguments")
280
-
return errors.New("config file not found and you haven't passed all arguments")
283
-
settings, err := cfg.GetSection("settings")
285
-
errorTask(c, "Validating arguments")
286
-
return errors.New("no settings section in your config")
289
-
// Only load from config if not provided as parameter
290
-
if configApiKey == "" {
291
-
configApiKey = settings.Key("api_key").String()
292
-
if configApiKey == "" {
293
-
errorTask(c, "Validating arguments")
294
-
return errors.New("couldn't find an api_key in your config")
298
-
if configApiURL == "" {
299
-
configApiURL = settings.Key("api_url").String()
300
-
if configApiURL == "" {
301
-
errorTask(c, "Validating arguments")
302
-
return errors.New("couldn't find an api_url in your config")
297
+
api_key, api_url, err := getClientStuff(c)
completeTask(c, "Arguments look fine!")
printTask(c, "Loading api client")
311
-
client := wakatime.NewClientWithOptions(configApiKey, configApiURL)
312
-
_, err := client.GetStatusBar()
303
+
client := wakatime.NewClientWithOptions(api_key, api_url)
304
+
_, err = client.GetStatusBar()
errorTask(c, "Loading api client")
···
completeTask(c, "Loading api client")
320
-
c.Println("Sending a test heartbeat to", styles.Muted.Render(configApiURL))
312
+
c.Println("Sending a test heartbeat to", styles.Muted.Render(api_url))
printTask(c, "Sending test heartbeat")
···
330
+
func Status(c *cobra.Command, args []string) error {
331
+
// Initialize a new context with task state
332
+
c.SetContext(context.WithValue(context.Background(), "taskState", &taskState{}))
334
+
printTask(c, "Validating arguments")
336
+
api_key, api_url, err := getClientStuff(c)
338
+
completeTask(c, "Arguments look fine!")
340
+
printTask(c, "Loading api client")
342
+
client := wakatime.NewClientWithOptions(api_key, api_url)
343
+
status, err := client.GetStatusBar()
345
+
errorTask(c, "Loading api client")
349
+
completeTask(c, "Loading api client")
351
+
c.Printf("\nLooks like you have coded today for %s today!\n", styles.Fancy.Render(utils.PrettyPrintTime(status.Data.GrandTotal.TotalSeconds)))
353
+
summary, err := client.GetLast7Days()
358
+
c.Printf("You have averaged %s over the last 7 days\n\n", styles.Fancy.Render(utils.PrettyPrintTime(int(summary.Data.DailyAverage))))
360
+
// Display top 5 projects with progress bars
361
+
if len(summary.Data.Projects) > 0 {
362
+
c.Println(styles.Fancy.Render("Top Projects:"))
364
+
// Determine how many projects to show (up to 5)
365
+
count := min(5, len(summary.Data.Projects))
367
+
// Find the longest project name for formatting
371
+
for i := range count {
372
+
project := summary.Data.Projects[i]
373
+
if len(project.Name) > longestName {
374
+
longestName = len(project.Name)
377
+
timeStr := utils.PrettyPrintTime(int(project.TotalSeconds))
378
+
if len(timeStr) > longestTime {
379
+
longestTime = len(timeStr)
383
+
// Display each project with a bar
384
+
for i := range count {
385
+
project := summary.Data.Projects[i]
387
+
// Format the project name and time with padding
388
+
paddedName := fmt.Sprintf("%-*s", longestName+2, project.Name)
389
+
timeStr := utils.PrettyPrintTime(int(project.TotalSeconds))
390
+
paddedTime := fmt.Sprintf("%-*s", longestTime+2, timeStr)
392
+
// Create the progress bar
395
+
percentage := project.Percent
396
+
for j := range barWidth {
397
+
if float64(j) < percentage/(100/float64(barWidth)) {
404
+
// Use different styles for different components
405
+
styledName := styles.Fancy.Render(paddedName)
406
+
styledTime := styles.Muted.Render(paddedTime)
407
+
styledBar := styles.Success.Render(bar)
408
+
styledPercent := styles.Warn.Render(fmt.Sprintf("%.2f%%", percentage))
410
+
// Print the formatted line
411
+
c.Printf(" %s %s %s %s\n", styledName, styledTime, styledBar, styledPercent)
417
+
// Display top 5 languages with progress bars
418
+
if len(summary.Data.Languages) > 0 {
419
+
c.Println(styles.Fancy.Render("Top Languages:"))
421
+
// Determine how many languages to show (up to 5)
422
+
count := min(5, len(summary.Data.Languages))
424
+
// Find the longest language name for formatting
428
+
for i := range count {
429
+
language := summary.Data.Languages[i]
430
+
if len(language.Name) > longestName {
431
+
longestName = len(language.Name)
434
+
timeStr := utils.PrettyPrintTime(int(language.TotalSeconds))
435
+
if len(timeStr) > longestTime {
436
+
longestTime = len(timeStr)
440
+
// Display each language with a bar
441
+
for i := range count {
442
+
language := summary.Data.Languages[i]
444
+
// Format the language name and time with padding
445
+
paddedName := fmt.Sprintf("%-*s", longestName+2, language.Name)
446
+
timeStr := utils.PrettyPrintTime(int(language.TotalSeconds))
447
+
paddedTime := fmt.Sprintf("%-*s", longestTime+2, timeStr)
449
+
// Create the progress bar
452
+
percentage := language.Percent
453
+
for j := range barWidth {
454
+
if float64(j) < percentage/(100/float64(barWidth)) {
461
+
// Use different styles for different components
462
+
styledName := styles.Fancy.Render(paddedName)
463
+
styledTime := styles.Muted.Render(paddedTime)
464
+
styledBar := styles.Success.Render(bar)
465
+
styledPercent := styles.Warn.Render(fmt.Sprintf("%.2f%%", percentage))
467
+
// Print the formatted line
468
+
c.Printf(" %s %s %s %s\n", styledName, styledTime, styledBar, styledPercent)