diff --git a/pkg/mod/waifu_bucket.go b/pkg/mod/waifu_bucket.go
new file mode 100644
index 0000000..55313ce
--- /dev/null
+++ b/pkg/mod/waifu_bucket.go
@@ -0,0 +1,9 @@
+package mod
+
+type WaifuBucket struct {
+ // the token of the bucket
+ Token string `json:"token"`
+
+ // The files contained in this bucket
+ Files []WaifuResponse[int] `json:"files"`
+}
diff --git a/pkg/mod/waifu_vault.go b/pkg/mod/waifu_vault.go
index 2b787a4..3692b71 100644
--- a/pkg/mod/waifu_vault.go
+++ b/pkg/mod/waifu_vault.go
@@ -20,4 +20,13 @@ type Waifuvalt interface {
// ModifyFile - modify an entry
ModifyFile(ctx context.Context, token string, options ModifyEntryPayload) (*WaifuResponse[int], error)
+
+ // CreateBucket - create a new bucket, buckets are bound to your IP, so you may only have one bucket per IP
+ CreateBucket(ctx context.Context) (*WaifuBucket, error)
+
+ // GetBucket - Get a bucket and all the files it contains
+ GetBucket(ctx context.Context, token string) (*WaifuBucket, error)
+
+ // DeleteBucket - Delete a bucket and all files it contains
+ DeleteBucket(ctx context.Context, token string) (bool, error)
}
diff --git a/pkg/mod/waifu_vault_put_opts.go b/pkg/mod/waifu_vault_put_opts.go
index 2ef7cc0..672c304 100644
--- a/pkg/mod/waifu_vault_put_opts.go
+++ b/pkg/mod/waifu_vault_put_opts.go
@@ -29,4 +29,7 @@ type WaifuvaultPutOpts struct {
// If this is true, then the file will be deleted as soon as it is accessed
OneTimeDownload bool `json:"oneTimeDownload"`
+
+ // If supplied, this file will be associated to that bucket
+ BucketToken string
}
diff --git a/pkg/waifu_vault_api.go b/pkg/waifu_vault_api.go
index 450f280..40ff495 100644
--- a/pkg/waifu_vault_api.go
+++ b/pkg/waifu_vault_api.go
@@ -90,7 +90,7 @@ func (re *api) UploadFile(ctx context.Context, options mod.WaifuvaultPutOpts) (*
"expires": options.Expires,
"hide_filename": options.HideFilename,
"one_time_download": options.OneTimeDownload,
- }, "")
+ }, options.BucketToken)
r, err := re.createRequest(ctx, http.MethodPut, uploadUrl, &body, writer)
if err != nil {
@@ -158,9 +158,6 @@ func (re *api) DeleteFile(ctx context.Context, token string) (bool, error) {
if err != nil {
return false, err
}
- if err != nil {
- return false, err
- }
bodyBytes, err := io.ReadAll(resp.Body)
bodyString := string(bodyBytes)
@@ -229,6 +226,54 @@ func (re *api) ModifyFile(ctx context.Context, token string, options mod.ModifyE
return getResponse[int](resp)
}
+func (re *api) CreateBucket(ctx context.Context) (*mod.WaifuBucket, error) {
+ restUrl := baseUrl + "/rest/bucket/createBucket"
+ r, err := re.createRequest(ctx, http.MethodGet, restUrl, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ resp, err := re.client.Do(r)
+ if err != nil {
+ return nil, err
+ }
+ return getBucketResponse(resp)
+}
+
+func (re *api) GetBucket(ctx context.Context, token string) (*mod.WaifuBucket, error) {
+ restUrl := baseUrl + "/rest/bucket"
+ type payload struct {
+ BucketToken string `json:"bucket_token"`
+ }
+ jsonData, err := json.Marshal(&payload{token})
+ r, err := re.createRequest(ctx, http.MethodPost, restUrl, bytes.NewBuffer(jsonData), nil)
+ if err != nil {
+ return nil, err
+ }
+ resp, err := re.client.Do(r)
+ if err != nil {
+ return nil, err
+ }
+ return getBucketResponse(resp)
+}
+
+func (re *api) DeleteBucket(ctx context.Context, token string) (bool, error) {
+ deleteUrl := baseUrl + "/rest/bucket/" + token
+ r, err := re.createRequest(ctx, http.MethodDelete, deleteUrl, nil, nil)
+ if err != nil {
+ return false, err
+ }
+ resp, err := re.client.Do(r)
+ defer resp.Body.Close()
+ err = checkError(resp)
+ if err != nil {
+ return false, err
+ }
+ bodyBytes, err := io.ReadAll(resp.Body)
+ bodyString := string(bodyBytes)
+
+ return bodyString == "true", nil
+}
+
func getUrl(obj map[string]any, path string) string {
baseRestUrl := fmt.Sprintf("%s/rest", baseUrl)
if path != "" {
@@ -253,19 +298,29 @@ func getUrl(obj map[string]any, path string) string {
return baseRestUrl
}
+func getBucketResponse(response *http.Response) (*mod.WaifuBucket, error) {
+ return readResponse(response, mod.WaifuBucket{})
+}
+
func getResponse[T string | int](response *http.Response) (*mod.WaifuResponse[T], error) {
+ return readResponse(response, mod.WaifuResponse[T]{})
+}
+
+func readResponse[T any](response *http.Response, target T) (*T, error) {
defer response.Body.Close()
err := checkError(response)
if err != nil {
return nil, err
}
- bodyBytes, _ := io.ReadAll(response.Body)
- var target = &mod.WaifuResponse[T]{}
- err = json.Unmarshal(bodyBytes, target)
+ bodyBytes, err := io.ReadAll(response.Body)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(bodyBytes, &target)
if err != nil {
return nil, err
}
- return target, nil
+ return &target, nil
}
func checkError(response *http.Response) error {
diff --git a/readme.md b/readme.md
index fbfac39..7329a66 100644
--- a/readme.md
+++ b/readme.md
@@ -18,6 +18,9 @@ This API contains 4 interactions:
3. [Delete File](#delete-file)
4. [Get File](#get-file)
5. [Modify Entry](#modify-entry)
+6. [Create Bucket](#create-bucket)
+7. [Get Bucket](#get-bucket)
+8. [Delete Bucket](#delete-bucket)
The package is namespaced to `waifuVault`, so to import it, simply:
@@ -470,3 +473,112 @@ func ToPtr[T any](x T) *T {
return &x
}
```
+
+### Create bucket
+
+Buckets are virtual collections that are linked to your IP and a token. When you create a bucket, you will receive a
+bucket token that you can use in [Get Bucket](#get-bucket) to get all the files in that bucket
+
+To create a bucket, use the `CreateBucket` function. This function does not take any arguments.
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ waifuVault "github.com/waifuvault/waifuVault-go-api/pkg"
+ "net/http"
+)
+
+func main() {
+ cx := context.Background()
+ api := waifuVault.NewWaifuvaltApi(http.Client{})
+ resp, err := api.CreateBucket(cx)
+ if err != nil {
+ fmt.Print(err)
+ }
+ fmt.Print(resp.Token) // the bucket token
+}
+```
+
+### Get Bucket
+
+To get a bucket, you must use the `GetBucket` function and supply the token.
+This function takes the following options as parameters:
+
+| Parameter | Type | Description | Required | Extra info |
+|-----------|----------|-------------------------|----------|------------|
+| `token` | `string` | The token of the bucket | true | |
+
+This will respond with the bucket and all the files the bucket contains.
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ waifuVault "github.com/waifuvault/waifuVault-go-api/pkg"
+ "net/http"
+)
+
+func main() {
+ cx := context.Background()
+ api := waifuVault.NewWaifuvaltApi(http.Client{})
+
+ // create the bucket
+ resp, err := api.CreateBucket(cx)
+ if err != nil {
+ fmt.Print(err)
+ }
+
+ // get the bucket
+ bucket, err := api.GetBucket(cx, resp.Token)
+ if err != nil {
+ fmt.Print(err)
+ }
+ fmt.Print(bucket.Files) // all the files in the bucket
+}
+```
+
+### Delete Bucket
+
+Deleting a bucket will delete the bucket and all the files it contains.
+
+To delete a bucket, you must call the `DeleteBucket` function with the following options as parameters:
+
+| Parameter | Type | Description | Required | Extra info |
+|-----------|----------|-----------------------------------|----------|------------|
+| `token` | `string` | The token of the bucket to delete | true | |
+
+> **NOTE:** `DeleteBucket` will only ever either return `true` or throw an exception if the token is invalid
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ waifuVault "github.com/waifuvault/waifuVault-go-api/pkg"
+ "net/http"
+)
+
+func main() {
+ cx := context.Background()
+ api := waifuVault.NewWaifuvaltApi(http.Client{})
+
+ // create the bucket
+ resp, err := api.CreateBucket(cx)
+ if err != nil {
+ fmt.Print(err)
+ }
+
+ // delete the bucket
+ delResp, err := api.DeleteBucket(cx, resp.Token)
+ if err != nil {
+ fmt.Print(err)
+ }
+ fmt.Print(delResp) // true
+}
+```