config.go (3776B)
1 package command 2 3 import ( 4 "bufio" 5 "errors" 6 "fmt" 7 "os" 8 "strconv" 9 "strings" 10 "time" 11 12 "code.dwrz.net/src/pkg/color" 13 "code.dwrz.net/src/pkg/dqs/command/help" 14 "code.dwrz.net/src/pkg/dqs/diet" 15 "code.dwrz.net/src/pkg/dqs/store" 16 "code.dwrz.net/src/pkg/dqs/user" 17 "code.dwrz.net/src/pkg/dqs/user/units" 18 ) 19 20 var Config = &command{ 21 execute: configure, 22 23 description: "configure the user settings", 24 help: help.Config, 25 name: "config", 26 } 27 28 func configure(args []string, date time.Time, store *store.Store) error { 29 u, err := store.GetUser() 30 if err != nil && !errors.Is(err, os.ErrNotExist) { 31 return err 32 } 33 if u == nil { 34 u = &user.DefaultUser 35 } 36 37 fmt.Printf( 38 "%sPress enter to skip a field.%s\n", 39 color.Italic, color.Reset, 40 ) 41 42 var in = bufio.NewReader(os.Stdin) 43 44 // Parse the name. 45 fmt.Print("Name: ") 46 line, err := in.ReadString('\n') 47 if err != nil { 48 return err 49 } 50 51 if line = strings.TrimSpace(line); line != "" { 52 u.Name = line 53 } 54 55 // Parse the birthday. 56 fmt.Print("Birthday (YYYYMMDD): ") 57 line, err = in.ReadString('\n') 58 if err != nil { 59 return err 60 } 61 62 if line = strings.TrimSpace(line); line != "" { 63 birthday, err := time.Parse("20060102", line) 64 if err != nil { 65 return err 66 } 67 68 u.Birthday = birthday 69 } 70 71 // Parse the units. 72 fmt.Print("Units (imperial|metric): ") 73 line, err = in.ReadString('\n') 74 if err != nil { 75 return err 76 } 77 78 if line = strings.TrimSpace(line); line != "" { 79 system := units.System(line) 80 81 if !units.Valid(system) { 82 return fmt.Errorf("invalid units") 83 } 84 85 u.Units = system 86 } 87 88 // Parse the height. 89 fmt.Print(fmt.Sprintf("Height (%s): ", u.Units.Height())) 90 line, err = in.ReadString('\n') 91 if err != nil { 92 return err 93 } 94 95 if line = strings.TrimSpace(line); line != "" { 96 height, err := strconv.ParseFloat(line, 64) 97 if err != nil { 98 return err 99 } 100 if height < 0 { 101 return fmt.Errorf("invalid height") 102 } 103 104 // Store all units in metric. 105 if u.Units == units.Imperial { 106 height = units.InchesToCentimeter(height) 107 } 108 109 u.Height = height 110 } 111 112 // Parse the weight. 113 fmt.Print(fmt.Sprintf("Weight (%s): ", u.Units.Weight())) 114 line, err = in.ReadString('\n') 115 if err != nil { 116 return err 117 } 118 119 if line = strings.TrimSpace(line); line != "" { 120 weight, err := strconv.ParseFloat(line, 64) 121 if err != nil { 122 return err 123 } 124 if weight < 0 { 125 return fmt.Errorf("invalid weight") 126 } 127 128 // Store all units in metric. 129 if u.Units == units.Imperial { 130 weight = units.PoundsToKilogram(weight) 131 } 132 133 u.Weight = weight 134 } 135 136 // Parse the body fat. 137 fmt.Print("Body Fat (%): ") 138 line, err = in.ReadString('\n') 139 if err != nil { 140 return err 141 } 142 143 if line = strings.TrimSpace(line); line != "" { 144 bf, err := strconv.ParseFloat(line, 64) 145 if err != nil { 146 return err 147 } 148 149 if bf < 0 || bf > 100 { 150 return fmt.Errorf("invalid body fat percentage") 151 } 152 153 u.BodyFat = bf 154 } 155 156 // Parse the diet. 157 fmt.Print("Diet (omnivore|vegan|vegetarian): ") 158 line, err = in.ReadString('\n') 159 if err != nil { 160 return err 161 } 162 163 if line = strings.TrimSpace(line); line != "" { 164 if !diet.Valid(diet.Diet(line)) { 165 return fmt.Errorf("unrecognized diet") 166 } 167 168 u.Diet = diet.Diet(line) 169 } 170 171 // Parse the Target Weight. 172 fmt.Print(fmt.Sprintf("Target Weight (%s): ", u.Units.Weight())) 173 line, err = in.ReadString('\n') 174 if err != nil { 175 return err 176 } 177 178 if line = strings.TrimSpace(line); line != "" { 179 tw, err := strconv.ParseFloat(line, 64) 180 if err != nil { 181 return err 182 } 183 184 if tw < 0 { 185 return fmt.Errorf("invalid target weight") 186 } 187 188 // Store all units in metric. 189 if u.Units == units.Imperial { 190 tw = units.PoundsToKilogram(tw) 191 } 192 193 u.TargetWeight = tw 194 } 195 196 if err := store.UpdateUser(u); err != nil { 197 return fmt.Errorf( 198 "failed to store user: %w", err, 199 ) 200 } 201 202 return nil 203 }