66 "fmt"
77 "net/http"
88 "os"
9- "strconv"
109 "strings"
1110 "text/tabwriter"
1211 "time"
@@ -23,8 +22,8 @@ type Response struct {
2322}
2423
2524// Retrieves data for user profile
26- func fetchData (itemID string , endpoint string , infoKey string ) (map [string ]interface {}, error ) {
27- url := config .BaseHackTheBoxAPIURL + endpoint + itemID
25+ func fetchData (itemID int , endpoint string , infoKey string ) (map [string ]interface {}, error ) {
26+ url := fmt . Sprintf ( "%s%s%d" , config .BaseHackTheBoxAPIURL , endpoint , itemID )
2827 config .GlobalConfig .Logger .Debug (fmt .Sprintf ("URL: %s" , url ))
2928
3029 resp , err := utils .HtbRequest (http .MethodGet , url , nil )
@@ -45,7 +44,7 @@ func fetchAndDisplayInfo(url, header string, params []string, elementType string
4544 w := utils .SetTabWriterHeader (header )
4645
4746 // Iteration on all machines / challenges / users argument
48- var itemID string
47+ var itemID int
4948 for _ , param := range params {
5049 if elementType == "Challenge" {
5150 config .GlobalConfig .Logger .Info ("Challenge search..." )
@@ -55,13 +54,12 @@ func fetchAndDisplayInfo(url, header string, params []string, elementType string
5554 }
5655 config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Challenge found: %v" , challenges ))
5756
58- // TODO: get this int
59- itemID = strconv .Itoa (challenges .ID )
57+ itemID = challenges .ID
6058 } else {
6159 itemID , _ = utils .SearchItemIDByName (param , elementType )
6260 }
6361
64- resp , err := utils .HtbRequest (http .MethodGet , ( url + itemID ), nil )
62+ resp , err := utils .HtbRequest (http .MethodGet , fmt . Sprintf ( "%s%d" , url , itemID ), nil )
6563 if err != nil {
6664 return err
6765 }
@@ -88,7 +86,6 @@ func fetchAndDisplayInfo(url, header string, params []string, elementType string
8886 url string
8987 }{
9088 {"Fortresses" , "/user/profile/progress/fortress/" },
91- {"Endgames" , "/user/profile/progress/endgame/" },
9289 {"Prolabs" , "/user/profile/progress/prolab/" },
9390 {"Activity" , "/user/profile/activity/" },
9491 }
@@ -203,7 +200,7 @@ func coreInfoCmd(machineName []string, challengeName []string, usernameName []st
203200
204201// getMachineStatus returns machine status
205202func getMachineStatus (data map [string ]interface {}) string {
206- if data ["retired" ].( float64 ) == 0 {
203+ if data ["retired" ] == false {
207204 return "No"
208205 }
209206 return "Yes"
@@ -223,144 +220,138 @@ func displayActiveMachine(header string) error {
223220 if err != nil {
224221 return err
225222 }
223+ if machineID == 0 {
224+ fmt .Println ("No machine is running" )
225+ return nil
226+ }
226227 machineType , err := utils .GetMachineType (machineID )
227228 if err != nil {
228229 return err
229230 }
230231 config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Machine Type: %s" , machineType ))
231232
232- var expiresTime string
233- switch {
234- case machineType == "release" :
235- expiresTime , err = utils .GetReleaseArenaExpiredTime ()
236- config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Expires Time: %s" , expiresTime ))
237- if err != nil {
238- return err
239- }
240- default :
241- expiresTime , err = utils .GetActiveExpiredTime ()
242- config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Expires Time:: %s" , expiresTime ))
243- if err != nil {
244- return err
245- }
233+ expiresTime , err := utils .GetExpiredTime (machineType )
234+ if err != nil {
235+ return err
246236 }
237+ config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Expires Time: %s" , expiresTime ))
247238
248- if machineID != "" {
249- config .GlobalConfig .Logger .Info ("Active machine found !" )
250- config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Machine ID: %s" , machineID ))
251- config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Expires At: %v" , expiresTime ))
239+ config .GlobalConfig .Logger .Info ("Active machine found !" )
240+ config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Machine ID: %d" , machineID ))
252241
253- layout := "2006-01-02 15:04:05"
254-
255- date , err := time .Parse (layout , expiresTime )
242+ if expiresTime != "Undefined" {
243+ err = checkIfExpiringSoon (expiresTime , machineID )
256244 if err != nil {
257- return fmt . Errorf ( "date conversion error: %v" , err )
245+ return err
258246 }
247+ }
259248
260- now := time .Now ()
261- config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Actual date: %v" , now ))
262-
263- timeLeft := date .Sub (now )
264- limit := 2 * time .Hour
265- if timeLeft > 0 && timeLeft <= limit {
266- var remainingTime string
267- if date .After (now ) {
268- duration := date .Sub (now )
269- hours := int (duration .Hours ())
270- minutes := int (duration .Minutes ()) % 60
271- seconds := int (duration .Seconds ()) % 60
272-
273- remainingTime = fmt .Sprintf ("%dh %dm %ds" , hours , minutes , seconds )
274-
275- }
276- // Extend time
277- isConfirmed := utils .AskConfirmation (fmt .Sprintf ("Would you like to extend the active machine time ? Remaining: %s" , remainingTime ))
278- if isConfirmed {
279- jsonData := []byte ("{\" machine_id\" :" + machineID + "}" )
280- resp , err := utils .HtbRequest (http .MethodPost , config .BaseHackTheBoxAPIURL + "/vm/extend" , jsonData )
281- if err != nil {
282- return err
283- }
284- var response Response
285- if err := json .NewDecoder (resp .Body ).Decode (& response ); err != nil {
286- return fmt .Errorf ("error decoding JSON response: %v" , err )
287- }
288-
289- inputLayout := time .RFC3339Nano
290-
291- date , err := time .Parse (inputLayout , response .ExpiresAt )
292- if err != nil {
293- return fmt .Errorf ("error decoding JSON response: %v" , err )
294- }
295-
296- outputLayout := "2006-01-02 -> 15h 04m 05s"
249+ tabwriter .NewWriter (os .Stdout , 0 , 0 , 3 , ' ' , tabwriter .Debug )
250+ w := utils .SetTabWriterHeader (header )
297251
298- formattedDate := date .Format (outputLayout )
252+ url := fmt .Sprintf ("%s/machine/profile/%d" , config .BaseHackTheBoxAPIURL , machineID )
253+ resp , err := utils .HtbRequest (http .MethodGet , url , nil )
254+ if err != nil {
255+ return err
256+ }
257+ info := utils .ParseJsonMessage (resp , "info" )
258+ // info := utils.ParseJsonMessage(resp, "data")
299259
300- fmt .Println (response .Message )
301- fmt .Printf ("Expires Date: %s\n " , formattedDate )
260+ data := info .(map [string ]interface {})
261+ status := utils .SetStatus (data )
262+ retiredStatus := getMachineStatus (data )
302263
303- }
304- }
264+ datetime , err := utils .ParseAndFormatDate (data ["release" ].(string ))
265+ if err != nil {
266+ return err
267+ }
268+ config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Machine Type: %s" , machineType ))
305269
306- tabwriter .NewWriter (os .Stdout , 0 , 0 , 3 , ' ' , tabwriter .Debug )
307- w := utils .SetTabWriterHeader (header )
270+ userSubscription , err := utils .GetUserSubscription ()
271+ if err != nil {
272+ return err
273+ }
274+ config .GlobalConfig .Logger .Debug (fmt .Sprintf ("User subscription: %s" , userSubscription ))
308275
309- url := fmt .Sprintf ("%s/machine/profile/%s" , config .BaseHackTheBoxAPIURL , machineID )
310- resp , err := utils .HtbRequest (http .MethodGet , url , nil )
276+ ip := "Undefined"
277+ _ = ip
278+ switch {
279+ case machineType == "release" :
280+ ip , err = utils .GetActiveReleaseArenaMachineIP ()
311281 if err != nil {
312282 return err
313283 }
314- info := utils .ParseJsonMessage (resp , "info" )
315- // info := utils.ParseJsonMessage(resp, "data")
316-
317- data := info .(map [string ]interface {})
318- status := utils .SetStatus (data )
319- retiredStatus := getMachineStatus (data )
320-
321- datetime , err := utils .ParseAndFormatDate (data ["release" ].(string ))
284+ case userSubscription == "vip+" :
285+ ip , err = utils .GetActiveMachineIP ()
322286 if err != nil {
323287 return err
324288 }
289+ default :
290+ ip = getIPStatus (data ).(string )
291+ }
325292
326- machineType , err := utils .GetMachineType (machineID )
327- if err != nil {
328- return err
329- }
330- config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Machine Type: %s" , machineType ))
293+ bodyData := fmt .Sprintf ("%v\t %v\t %v\t %v\t %v\t %v\t %v\t %v\t %v\n " ,
294+ data ["name" ], data ["os" ], retiredStatus ,
295+ data ["difficultyText" ], data ["stars" ],
296+ ip , status , data ["last_reset_time" ], datetime )
331297
332- userSubscription , err := utils .GetUserSubscription ()
333- if err != nil {
334- return err
335- }
336- config .GlobalConfig .Logger .Debug (fmt .Sprintf ("User subscription: %s" , userSubscription ))
298+ utils .SetTabWriterData (w , bodyData )
299+ w .Flush ()
300+ return nil
301+ }
302+
303+ func checkIfExpiringSoon (expiresTime string , machineID int ) error {
304+ layout := "2006-01-02 15:04:05"
337305
338- ip := "Undefined"
339- _ = ip
340- switch {
341- case machineType == "release" :
342- ip , err = utils .GetActiveReleaseArenaMachineIP ()
306+ date , err := time .Parse (layout , expiresTime )
307+ if err != nil {
308+ return fmt .Errorf ("date conversion error: %v" , err )
309+ }
310+
311+ now := time .Now ()
312+ config .GlobalConfig .Logger .Debug (fmt .Sprintf ("Actual date: %v" , now ))
313+
314+ timeLeft := date .Sub (now )
315+ limit := 2 * time .Hour
316+ if timeLeft > 0 && timeLeft <= limit {
317+ var remainingTime string
318+ if date .After (now ) {
319+ duration := date .Sub (now )
320+ hours := int (duration .Hours ())
321+ minutes := int (duration .Minutes ()) % 60
322+ seconds := int (duration .Seconds ()) % 60
323+
324+ remainingTime = fmt .Sprintf ("%dh %dm %ds" , hours , minutes , seconds )
325+
326+ }
327+ // Extend time
328+ isConfirmed := utils .AskConfirmation (fmt .Sprintf ("Would you like to extend the active machine time ? Remaining: %s" , remainingTime ))
329+ if isConfirmed {
330+ jsonData := []byte (fmt .Sprintf (`{"machine_id":%d}` , machineID ))
331+ resp , err := utils .HtbRequest (http .MethodPost , config .BaseHackTheBoxAPIURL + "/vm/extend" , jsonData )
343332 if err != nil {
344333 return err
345334 }
346- case userSubscription == "vip+" :
347- ip , err = utils .GetActiveMachineIP ()
335+ var response Response
336+ if err := json .NewDecoder (resp .Body ).Decode (& response ); err != nil {
337+ return fmt .Errorf ("error decoding JSON response: %v" , err )
338+ }
339+
340+ inputLayout := "2006-01-02 15:04:05"
341+
342+ date , err := time .Parse (inputLayout , response .ExpiresAt )
348343 if err != nil {
349- return err
344+ return fmt . Errorf ( "error decoding JSON response: %v" , err )
350345 }
351- default :
352- ip = getIPStatus (data ).(string )
353- }
354346
355- bodyData := fmt .Sprintf ("%v\t %v\t %v\t %v\t %v\t %v\t %v\t %v\t %v\n " ,
356- data ["name" ], data ["os" ], retiredStatus ,
357- data ["difficultyText" ], data ["stars" ],
358- ip , status , data ["last_reset_time" ], datetime )
347+ outputLayout := "2006-01-02 - 15h 04m 05s"
359348
360- utils .SetTabWriterData (w , bodyData )
361- w .Flush ()
362- } else {
363- fmt .Println ("No machine is running" )
349+ formattedDate := date .Format (outputLayout )
350+
351+ fmt .Println (response .Message )
352+ fmt .Printf ("Expires Date: %s\n " , formattedDate )
353+
354+ }
364355 }
365356 return nil
366357}
0 commit comments