Skip to content

Commit 1ac908f

Browse files
committed
add url add command
1 parent 07de009 commit 1ac908f

File tree

4 files changed

+186
-3
lines changed

4 files changed

+186
-3
lines changed

cmd/curio/market.go

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package main
22

33
import (
4+
"bufio"
5+
"encoding/json"
46
"errors"
57
"fmt"
8+
"net/http"
69
"net/url"
710
"os"
811
"strconv"
12+
"strings"
913

1014
"github.com/google/uuid"
1115
"github.com/mitchellh/go-homedir"
@@ -27,6 +31,7 @@ var marketCmd = &cli.Command{
2731
Subcommands: []*cli.Command{
2832
marketSealCmd,
2933
marketImportdataCmd,
34+
marketAddOfflineURLCmd,
3035
},
3136
}
3237

@@ -204,3 +209,162 @@ var marketImportdataCmd = &cli.Command{
204209
return nil
205210
},
206211
}
212+
213+
var marketAddOfflineURLCmd = &cli.Command{
214+
Name: "add-url",
215+
Usage: "Add URL to fetch data for offline deals",
216+
Flags: []cli.Flag{
217+
&cli.StringFlag{
218+
Name: "file",
219+
Usage: "CSV file location to use for multiple deal input. Each line in the file should be in the format 'uuid,raw size,url,header1,header2...'\"",
220+
Required: true,
221+
},
222+
&cli.StringFlag{
223+
Name: "header",
224+
Aliases: []string{"H"},
225+
Usage: "Custom `HEADER` to include in the HTTP request",
226+
Required: true,
227+
},
228+
&cli.StringFlag{
229+
Name: "url",
230+
Aliases: []string{"u"},
231+
Usage: "`URL` to send the request to",
232+
Required: true,
233+
},
234+
},
235+
ArgsUsage: "<deal UUID> <raw size/car size>",
236+
Action: func(cctx *cli.Context) error {
237+
if !cctx.IsSet("file") && cctx.Args().Len() != 2 {
238+
return xerrors.Errorf("incorrect number of arguments")
239+
}
240+
241+
ctx := reqcontext.ReqContext(cctx)
242+
dep, err := deps.GetDepsCLI(ctx, cctx)
243+
if err != nil {
244+
return err
245+
}
246+
247+
if cctx.IsSet("file") {
248+
// Read file line by line
249+
fileStr := cctx.String("file")
250+
loc, err := homedir.Expand(fileStr)
251+
if err != nil {
252+
return err
253+
}
254+
file, err := os.Open(loc)
255+
if err != nil {
256+
return err
257+
}
258+
defer file.Close()
259+
scanner := bufio.NewScanner(file)
260+
for scanner.Scan() {
261+
line := scanner.Text()
262+
// Extract pieceCid, pieceSize and MinerAddr from line
263+
parts := strings.SplitN(line, ",", 4)
264+
if parts[0] == "" || parts[1] == "" || parts[2] == "" {
265+
return fmt.Errorf("empty column value in the input file at %s", line)
266+
}
267+
268+
uuid := parts[0]
269+
size, err := strconv.ParseInt(parts[1], 10, 64)
270+
if err != nil {
271+
return fmt.Errorf("failed to parse size %w", err)
272+
}
273+
274+
url := parts[2]
275+
276+
if parts[3] != "" {
277+
header := http.Header{}
278+
for _, s := range strings.Split(parts[3], ",") {
279+
key, value, found := strings.Cut(s, ":")
280+
if !found {
281+
return fmt.Errorf("invalid header format, expected key:value")
282+
}
283+
header.Set(strings.TrimSpace(key), strings.TrimSpace(value))
284+
}
285+
286+
hdr, err := json.Marshal(header)
287+
if err != nil {
288+
return xerrors.Errorf("marshalling headers: %w", err)
289+
}
290+
_, err = dep.DB.Exec(ctx, `INSERT INTO market_offline_urls (
291+
uuid,
292+
url,
293+
headers,
294+
raw_size
295+
) VALUES ($1, $2, $3, $4);`,
296+
uuid, url, hdr, size)
297+
if err != nil {
298+
return xerrors.Errorf("adding details to DB: %w", err)
299+
}
300+
} else {
301+
_, err = dep.DB.Exec(ctx, `INSERT INTO market_offline_urls (
302+
uuid,
303+
url,
304+
raw_size
305+
) VALUES ($1, $2, $3, $4);`,
306+
uuid, url, size)
307+
if err != nil {
308+
return xerrors.Errorf("adding details to DB: %w", err)
309+
}
310+
}
311+
312+
if err := scanner.Err(); err != nil {
313+
return err
314+
}
315+
}
316+
}
317+
318+
url := cctx.String("url")
319+
320+
headerValue := cctx.StringSlice("header")
321+
322+
uuid := cctx.Args().First()
323+
324+
sizeStr := cctx.Args().Get(1)
325+
size, err := strconv.ParseInt(sizeStr, 10, 64)
326+
if err != nil {
327+
return xerrors.Errorf("parsing size: %w", err)
328+
}
329+
330+
if cctx.IsSet("header") {
331+
// Split the header into key-value
332+
header := http.Header{}
333+
for _, s := range headerValue {
334+
key, value, found := strings.Cut(s, ":")
335+
if !found {
336+
return fmt.Errorf("invalid header format, expected key:value")
337+
}
338+
header.Set(strings.TrimSpace(key), strings.TrimSpace(value))
339+
}
340+
341+
hdr, err := json.Marshal(header)
342+
if err != nil {
343+
return xerrors.Errorf("marshalling headers: %w", err)
344+
}
345+
346+
_, err = dep.DB.Exec(ctx, `INSERT INTO market_offline_urls (
347+
uuid,
348+
url,
349+
headers,
350+
raw_size
351+
) VALUES ($1, $2, $3, $4);`,
352+
uuid, url, hdr, size)
353+
if err != nil {
354+
return xerrors.Errorf("adding details to DB: %w", err)
355+
}
356+
} else {
357+
_, err = dep.DB.Exec(ctx, `INSERT INTO market_offline_urls (
358+
uuid,
359+
url,
360+
raw_size
361+
) VALUES ($1, $2, $3, $4);`,
362+
uuid, url, size)
363+
if err != nil {
364+
return xerrors.Errorf("adding details to DB: %w", err)
365+
}
366+
}
367+
368+
return nil
369+
},
370+
}

documentation/en/curio-cli/curio.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ USAGE:
549549
COMMANDS:
550550
seal start sealing a deal sector early
551551
import-data Import data for offline deal
552+
add-url Add URL to fetch data for offline deals
552553
help, h Shows a list of commands or help for one command
553554
554555
OPTIONS:
@@ -582,6 +583,21 @@ OPTIONS:
582583
--help, -h show help
583584
```
584585

586+
### curio market add-url
587+
```
588+
NAME:
589+
curio market add-url - Add URL to fetch data for offline deals
590+
591+
USAGE:
592+
curio market add-url [command options] <deal UUID> <raw size/car size>
593+
594+
OPTIONS:
595+
--file value CSV file location to use for multiple deal input. Each line in the file should be in the format 'uuid,raw size,url,header1,header2...'"
596+
--header HEADER, -H HEADER Custom HEADER to include in the HTTP request
597+
--url URL, -u URL URL to send the request to
598+
--help, -h show help
599+
```
600+
585601
## curio fetch-params
586602
```
587603
NAME:

harmony/harmonydb/sql/20240730-market-migration.sql renamed to harmony/harmonydb/sql/20240731-market-migration.sql

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,17 @@ $$ LANGUAGE plpgsql;
230230
-- This table can be used to track remote piece for offline deals
231231
-- The entries must be created by users
232232
CREATE TABLE market_offline_urls (
233-
piece_cid TEXT NOT NULL,
233+
uuid TEXT NOT NULL,
234234

235235
url TEXT NOT NULL,
236236
headers jsonb NOT NULL DEFAULT '{}',
237237

238238
raw_size BIGINT NOT NULL,
239239

240-
unique (piece_cid)
240+
CONSTRAINT market_offline_urls_uuid_fk FOREIGN KEY (uuid)
241+
REFERENCES market_mk12_deal_pipeline (uuid)
242+
ON DELETE CASCADE,
243+
CONSTRAINT market_offline_urls_uuid_unique UNIQUE (uuid)
241244
);
242245

243246
-- This table is used for coordinating libp2p nodes

tasks/storage-market/storage_market.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ func (d *CurioStorageDealMarket) findURLForOfflineDeals(ctx context.Context, dea
378378
}
379379

380380
err := d.db.Select(ctx, &goUrls, `SELECT url, headers, raw_size
381-
FROM market_offline_urls WHERE piece_cid = $1`, pcid)
381+
FROM market_offline_urls WHERE piece_cid = $1 AND uuid = $2`, pcid, deal)
382382

383383
if err != nil {
384384
return false, xerrors.Errorf("getting url and headers from db: %w", err)

0 commit comments

Comments
 (0)