Files
gravatar-recon/utils/print.go
2025-09-25 19:15:16 +02:00

169 lines
3.8 KiB
Go

package utils
import (
"fmt"
"io"
"net/http"
"os"
"reflect"
"sort"
"strings"
"github.com/charmbracelet/lipgloss"
gopixels "github.com/saran13raj/go-pixels"
)
var (
grey = lipgloss.Color("#7d7d7d")
green = lipgloss.Color("#a6e3a1")
blue = lipgloss.Color("#7287fd")
greyStyle = lipgloss.NewStyle().Foreground(grey)
greenStyle = lipgloss.NewStyle().Foreground(green)
titleStyle = lipgloss.NewStyle().Bold(true).Foreground(blue)
)
func PrintStruct(s any, indent int) {
prefix := strings.Repeat(" ", indent)
v := reflect.ValueOf(s)
if !v.IsValid() {
return
}
t := reflect.TypeOf(s)
for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
if v.IsNil() {
return
}
v = v.Elem()
t = v.Type()
}
switch v.Kind() {
case reflect.Struct:
if v.NumField() == 0 {
fmt.Println(prefix + greyStyle.Render("No data found"))
fmt.Println("")
return
}
printed := 0
for i := 0; i < v.NumField(); i++ {
field := t.Field(i).Name
value := v.Field(i)
if !value.CanInterface() {
continue
}
if !value.IsValid() || (value.Kind() == reflect.String && value.String() == "") {
continue
}
if value.Kind() == reflect.String && value.String() == "0001-01-01 00:00:00 +0000 UTC" {
continue
}
printed++
switch value.Kind() {
case reflect.Struct, reflect.Slice, reflect.Array, reflect.Ptr, reflect.Map, reflect.Interface:
fmt.Println(prefix + greyStyle.Render(field+":"))
PrintStruct(value.Interface(), indent+1)
case reflect.String:
fmt.Printf("%s%s %s\n", prefix, greyStyle.Render(field+":"), greenStyle.Render(fmt.Sprintf("%q", value.Interface())))
default:
fmt.Printf("%s%s %s\n", prefix, greyStyle.Render(field+":"), greenStyle.Render(fmt.Sprintf("%v", value.Interface())))
}
}
if printed == 0 {
fmt.Println(prefix + greyStyle.Render("No data found"))
}
fmt.Println("")
case reflect.Slice, reflect.Array:
if v.Len() == 0 {
fmt.Println(prefix + greyStyle.Render("No data found"))
fmt.Println("")
return
}
for i := 0; i < v.Len(); i++ {
PrintStruct(v.Index(i).Interface(), indent)
}
case reflect.Map:
if v.Len() == 0 {
fmt.Println(prefix + greyStyle.Render("No data found"))
return
}
keys := v.MapKeys()
keyStrs := make([]string, len(keys))
for i, k := range keys {
keyStrs[i] = fmt.Sprintf("%v", k.Interface())
}
sort.Strings(keyStrs)
for _, keyStr := range keyStrs {
for _, k := range keys {
if fmt.Sprintf("%v", k.Interface()) == keyStr {
val := v.MapIndex(k)
fmt.Println(prefix + greyStyle.Render(fmt.Sprintf("%v:", k.Interface())))
PrintStruct(val.Interface(), indent+1)
}
}
}
default:
fmt.Println(prefix + greenStyle.Render(fmt.Sprintf("%v", v.Interface())))
}
}
func Header() {
asciiArt := " _____ _ \n| __|___ ___ _ _ ___| |_ ___ ___ ___ ___ ___ ___ ___ ___ \n| | | _| .'| | | .'| _| .'| _|___| _| -_| _| . | |\n|_____|_| |__,|\\_/|__,|_| |__,|_| |_| |___|___|___|_|_|"
grey := lipgloss.Color("#7d7d7d")
greyStyle := lipgloss.NewStyle().Foreground(grey)
fmt.Println(
greyStyle.Render(lipgloss.JoinVertical(lipgloss.Right, asciiArt, "@anotherhadi\n")),
)
}
func PrintTitle(title string) {
fmt.Println(titleStyle.Render(title) + "\n")
}
func PrintNoResultFound() {
fmt.Println(titleStyle.Render("No result found"))
}
func PrintAvatar(url string) {
if url == "" {
return
}
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
tmpfile, err := os.CreateTemp("", "avatar-*.png")
if err != nil {
return
}
defer os.Remove(tmpfile.Name())
_, err = io.Copy(tmpfile, resp.Body)
if err != nil {
return
}
output, err := gopixels.FromImagePath(tmpfile.Name(), 30, 25, "halfcell", true)
if err != nil {
return
}
fmt.Println(output + "\n")
}