Skip to content

Commit 35a970d

Browse files
authored
Merge pull request #130 from GoToolSharing/dev
Release v1.7.0
2 parents 1951106 + 6b333c7 commit 35a970d

File tree

20 files changed

+341
-539
lines changed

20 files changed

+341
-539
lines changed

.github/workflows/go.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@ jobs:
1717
runs-on: ubuntu-latest
1818
strategy:
1919
matrix:
20-
go: ['1.19', '1.20', '1.21']
20+
go: ['1.20', '1.22', '1.23', '1.24']
2121
os: [ 'linux', 'windows', 'darwin' ]
2222
arch: [ 'amd64', 'arm64' ]
2323
outputs:
2424
commit-hash: ${{ steps.get_commit.outputs.commit }}
2525

2626
steps:
27-
- uses: actions/checkout@v3
27+
- uses: actions/checkout@v4
2828

2929
- name: Set up Go
30-
uses: actions/setup-go@v4
30+
uses: actions/setup-go@v5
3131
with:
3232
go-version: ${{ matrix.go }}
3333

3434
- name: Build
3535
env:
3636
GOOS: ${{ matrix.os }}
3737
GOARCH: ${{ matrix.arch }}
38-
run: go build -v ./...
38+
run: go build -v ./...

.github/workflows/golangci-lint.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,22 @@ jobs:
1414

1515
steps:
1616
- name: Checkout code
17-
uses: actions/checkout@v3
17+
uses: actions/checkout@v4
1818

1919
- name: Set up Go
20-
uses: actions/setup-go@v4
20+
uses: actions/setup-go@v5
2121
with:
22-
go-version: 1.19
22+
go-version: 1.24
2323

2424
- name: Run golangci-lint
25-
uses: golangci/golangci-lint-action@v3
25+
uses: golangci/golangci-lint-action@v6.3.2
2626
with:
2727
version: latest
28-
skip-pkg-cache: true
29-
skip-build-cache: true
28+
skip-cache: true
29+
skip-save-cache: true
3030

3131
- name: Upload lint results
32-
uses: actions/upload-artifact@v2
32+
uses: actions/upload-artifact@v4
3333
if: failure()
3434
with:
3535
name: golangci-lint-results

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ jobs:
1313
release:
1414
runs-on: ubuntu-latest
1515
steps:
16-
- uses: actions/checkout@v3
16+
- uses: actions/checkout@v4
1717
with:
1818
fetch-depth: 0
1919

2020
- name: Set up Go
21-
uses: actions/setup-go@v4
21+
uses: actions/setup-go@v5
2222
with:
2323
go-version: '1.20'
2424

2525
- name: Release
26-
uses: goreleaser/goreleaser-action@v4
26+
uses: goreleaser/goreleaser-action@v6
2727
with:
2828
distribution: goreleaser
2929
version: latest

cmd/info.go

Lines changed: 105 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
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
205202
func 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

Comments
 (0)