1package client
2
3import (
4  "fmt"
5  "github.com/docopt/docopt-go"
6  "github.com/eventials/go-tus"
7  "github.com/eventials/go-tus/leveldbstore"
8  "github.com/jackhftang/tusc/internal/util"
9  "net/http"
10  "os"
11  "strings"
12)
13
14const clientUsage = `tusc client
15
16Usage:
17  tusc (client|c) <url> <file> [-H <header>]... [options]
18  tusc (client|c) --help
19
20Options:
21  -r --resumable            Save meta data for resumable uploads [default: false]
22  --store PATH              Path to save meta data for resume [default: ./.tusc]
23  --chunk-size BYTE         Size of chunks of file [default: 2097152]
24  --override-patch-method   Sending a POST request instead of PATCH [default: false]
25`
26
27type ClientConf struct {
28  file   string
29  url    string
30  resume bool
31}
32
33func Client() {
34  var err error
35
36  var conf ClientConf
37  arguments, _ := docopt.ParseDoc(clientUsage)
38  conf.file, _ = arguments.String("<file>")
39  conf.url, _ = arguments.String("<url>")
40  conf.resume = util.GetBool(arguments, "--resumable")
41
42  // open file
43  f, err := os.Open(conf.file)
44  if err != nil {
45    util.ExitWithMessages("Cannot open file: " + conf.file)
46  }
47  defer f.Close()
48
49  // create the tus client
50  var store tus.Store
51  if conf.resume {
52    path := util.GetString(arguments, "--store")
53    store, err = leveldbstore.NewLeveldbStore(path)
54    if err != nil {
55      util.ExitWithMessages("Cannot Open "+path, clientUsage)
56    }
57  }
58
59  // create HTTP header
60  header := make(http.Header)
61  nHdr := arguments["-H"].(int)
62  hdrs := util.GetSliceString(arguments, "<header>")
63  for i := 0; i < nHdr; i += 1 {
64    h := hdrs[i]
65    ix := strings.Index(h, ":")
66    if ix < 0 {
67      continue
68    }
69    hdr := h[0:ix]
70    val := h[ix+1:]
71    fmt.Println(hdr)
72    header.Set(hdr, val)
73  }
74
75  client, _ := tus.NewClient(conf.url, &tus.Config{
76    ChunkSize:           util.GetInt64(arguments, "--chunk-size"),
77    OverridePatchMethod: util.GetBool(arguments, "--override-patch-method"),
78    Resume:              conf.resume,
79    Store:               store,
80    Header:              header,
81    HttpClient:          nil,
82  })
83
84  // create an upload from a file.
85  var upload *tus.Upload
86  if upload, err = tus.NewUploadFromFile(f); err != nil {
87    util.ExitWithMessages("Cannot create upload from file: " + f.Name())
88  }
89
90  // create the uploader.
91  var uploader *tus.Uploader
92  if conf.resume {
93    uploader, err = client.CreateOrResumeUpload(upload)
94  } else {
95    uploader, err = client.CreateUpload(upload)
96  }
97  if err != nil {
98    util.ExitWithMessages("Failed to upload", err.Error())
99  }
100
101  fmt.Println(uploader.Url())
102
103  // start the uploading process.
104  if err = uploader.Upload(); err != nil {
105    util.ExitWithMessages("Upload incomplete", err.Error())
106  }
107}
108