feat(cli): add a list retrievals command
Currently, there is no way to inspect retrievals on a client. This adds said command, allow with corresponding APIs
This commit is contained in:
+187
@@ -92,6 +92,7 @@ var clientCmd = &cli.Command{
|
||||
WithCategory("retrieval", clientFindCmd),
|
||||
WithCategory("retrieval", clientRetrieveCmd),
|
||||
WithCategory("retrieval", clientCancelRetrievalDealCmd),
|
||||
WithCategory("retrieval", clientListRetrievalsCmd),
|
||||
WithCategory("util", clientCommPCmd),
|
||||
WithCategory("util", clientCarGenCmd),
|
||||
WithCategory("util", clientBalancesCmd),
|
||||
@@ -1209,6 +1210,192 @@ var clientRetrieveCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var clientListRetrievalsCmd = &cli.Command{
|
||||
Name: "list-retrievals",
|
||||
Usage: "List retrieval market deals",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "verbose",
|
||||
Aliases: []string{"v"},
|
||||
Usage: "print verbose deal details",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "color",
|
||||
Usage: "use color in display output",
|
||||
Value: true,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "show-failed",
|
||||
Usage: "show failed/failing deals",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "completed",
|
||||
Usage: "show completed retrievals",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "watch",
|
||||
Usage: "watch deal updates in real-time, rather than a one time list",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
api, closer, err := GetFullNodeAPIV1(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
verbose := cctx.Bool("verbose")
|
||||
color := cctx.Bool("color")
|
||||
watch := cctx.Bool("watch")
|
||||
showFailed := cctx.Bool("show-failed")
|
||||
completed := cctx.Bool("completed")
|
||||
|
||||
localDeals, err := api.ClientListRetrievals(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if watch {
|
||||
updates, err := api.ClientGetRetrievalUpdates(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
tm.Clear()
|
||||
tm.MoveCursor(1, 1)
|
||||
|
||||
err = outputRetrievalDeals(ctx, tm.Screen, localDeals, verbose, color, showFailed, completed)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tm.Flush()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case updated := <-updates:
|
||||
var found bool
|
||||
for i, existing := range localDeals {
|
||||
if existing.ID == updated.ID {
|
||||
localDeals[i] = updated
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
localDeals = append(localDeals, updated)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outputRetrievalDeals(ctx, cctx.App.Writer, localDeals, verbose, color, showFailed, completed)
|
||||
},
|
||||
}
|
||||
|
||||
func outputRetrievalDeals(ctx context.Context, out io.Writer, localDeals []lapi.RetrievalInfo, verbose bool, color bool, showFailed bool, completed bool) error {
|
||||
var deals []api.RetrievalInfo
|
||||
for _, deal := range localDeals {
|
||||
if !showFailed && retrievalmarket.IsTerminalError(deal.Status) {
|
||||
continue
|
||||
}
|
||||
if !completed && retrievalmarket.IsTerminalSuccess(deal.Status) {
|
||||
continue
|
||||
}
|
||||
deals = append(deals, deal)
|
||||
}
|
||||
|
||||
tableColumns := []tablewriter.Column{
|
||||
tablewriter.Col("PayloadCID"),
|
||||
tablewriter.Col("DealId"),
|
||||
tablewriter.Col("Provider"),
|
||||
tablewriter.Col("Status"),
|
||||
tablewriter.Col("PricePerByte"),
|
||||
tablewriter.Col("Received"),
|
||||
tablewriter.Col("TotalPaid"),
|
||||
}
|
||||
|
||||
if verbose {
|
||||
tableColumns = append(tableColumns,
|
||||
tablewriter.Col("PieceCID"),
|
||||
tablewriter.Col("UnsealPrice"),
|
||||
tablewriter.Col("BytesPaidFor"),
|
||||
tablewriter.Col("TransferChannelID"),
|
||||
tablewriter.Col("TransferStatus"),
|
||||
)
|
||||
}
|
||||
tableColumns = append(tableColumns, tablewriter.NewLineCol("Message"))
|
||||
|
||||
w := tablewriter.New(tableColumns...)
|
||||
|
||||
for _, d := range deals {
|
||||
w.Write(toRetrievalOutput(d, color, verbose))
|
||||
}
|
||||
|
||||
return w.Flush(out)
|
||||
}
|
||||
|
||||
func toRetrievalOutput(d api.RetrievalInfo, color bool, verbose bool) map[string]interface{} {
|
||||
|
||||
payloadCID := d.PayloadCID.String()
|
||||
provider := d.Provider.String()
|
||||
if !verbose {
|
||||
payloadCID = ellipsis(payloadCID, 8)
|
||||
provider = ellipsis(provider, 8)
|
||||
}
|
||||
|
||||
retrievalOutput := map[string]interface{}{
|
||||
"PayloadCID": payloadCID,
|
||||
"DealId": d.ID,
|
||||
"Provider": provider,
|
||||
"Status": retrievalStatusString(color, d.Status),
|
||||
"PricePerByte": types.FIL(d.PricePerByte),
|
||||
"Received": units.BytesSize(float64(d.BytesReceived)),
|
||||
"TotalPaid": types.FIL(d.TotalPaid),
|
||||
"Message": d.Message,
|
||||
}
|
||||
|
||||
if verbose {
|
||||
transferChannelID := ""
|
||||
if d.TransferChannelID != nil {
|
||||
transferChannelID = d.TransferChannelID.String()
|
||||
}
|
||||
transferStatus := ""
|
||||
if d.DataTransfer != nil {
|
||||
transferStatus = datatransfer.Statuses[d.DataTransfer.Status]
|
||||
}
|
||||
pieceCID := ""
|
||||
if d.PieceCID != nil {
|
||||
pieceCID = d.PieceCID.String()
|
||||
}
|
||||
|
||||
retrievalOutput["PieceCID"] = pieceCID
|
||||
retrievalOutput["UnsealPrice"] = types.FIL(d.UnsealPrice)
|
||||
retrievalOutput["BytesPaidFor"] = units.BytesSize(float64(d.BytesPaidFor))
|
||||
retrievalOutput["TransferChannelID"] = transferChannelID
|
||||
retrievalOutput["TransferStatus"] = transferStatus
|
||||
}
|
||||
return retrievalOutput
|
||||
}
|
||||
|
||||
func retrievalStatusString(c bool, status retrievalmarket.DealStatus) string {
|
||||
s := retrievalmarket.DealStatuses[status]
|
||||
if !c {
|
||||
return s
|
||||
}
|
||||
|
||||
if retrievalmarket.IsTerminalError(status) {
|
||||
return color.RedString(s)
|
||||
}
|
||||
if retrievalmarket.IsTerminalSuccess(status) {
|
||||
return color.GreenString(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
var clientInspectDealCmd = &cli.Command{
|
||||
Name: "inspect-deal",
|
||||
Usage: "Inspect detailed information about deal's lifecycle and the various stages it goes through",
|
||||
|
||||
Reference in New Issue
Block a user