Skip to content

Commit

Permalink
feat: add --stdin option to upload command (#298)
Browse files Browse the repository at this point in the history
* feat: add --stdin option to upload command

feat: add --hide-usage option to stamp list command

fix: set error code on runtime and parsing error

* refactor: remove exit()

* test: adjust error messages

feat: add optional headers

* docs: update stamp automation examples

feat: add --name flag and content type detection to stdin upload

* docs: write about headers and upload types

* docs: update toc

* fix: change stdin check interval ms

* docs: improve readability

Co-authored-by: Attila Gazso <[email protected]>

* refactor: improve stdin read code

Co-authored-by: Attila Gazso <[email protected]>
  • Loading branch information
Cafe137 and agazso authored Nov 17, 2021
1 parent d825947 commit 42ae5da
Show file tree
Hide file tree
Showing 14 changed files with 342 additions and 122 deletions.
145 changes: 109 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,43 @@ This project is intended to be used with **Bee version <!-- SUPPORTED_BEE_START

# Table of Contents

* [Swarm-CLI](#swarm-cli)
* [Table of Contents](#table-of-contents)
* [Demo](#demo)
* [Purchasing a Postage Stamp](#purchasing-a-postage-stamp)
* [Uploading a File](#uploading-a-file)
* [Creating an Identity](#creating-an-identity)
* [Uploading to a Feed](#uploading-to-a-feed)
* [Description](#description)
* [Installation](#installation)
* [From npm](#from-npm)
* [From source](#from-source)
* [Usage](#usage)
* [Commands](#commands)
* [Example usage](#example-usage)
* [Usability Features](#usability-features)
* [Autocomplete](#autocomplete)
* [Numerical Separator and Units](#numerical-separator-and-units)
* [Stamp Picker](#stamp-picker)
* [Identity Picker](#identity-picker)
* [Human Readable Topics](#human-readable-topics)
* [Manifest address scheme](#manifest-address-scheme)
* [Automating tasks with Swarm-CLI](#automating-tasks-with-swarm-cli)
* [Connectivity](#connectivity)
* [Postage Stamps](#postage-stamps)
* [Uploading](#uploading)
* [Config](#config)
* [Assignment priority](#assignment-priority)
* [System environment](#system-environment)
* [Development](#development)
* [Contribute](#contribute)
* [Maintainers](#maintainers)
* [License](#license)
- [Swarm-CLI](#swarm-cli)
- [Table of Contents](#table-of-contents)
- [Demo](#demo)
* [Purchasing a Postage Stamp](#purchasing-a-postage-stamp)
* [Uploading a File](#uploading-a-file)
* [Creating an Identity](#creating-an-identity)
* [Uploading to a Feed](#uploading-to-a-feed)
- [Description](#description)
* [Installation](#installation)
+ [From npm](#from-npm)
+ [From source](#from-source)
* [Usage](#usage)
* [Commands](#commands)
* [Example usage](#example-usage)
* [Usability Features](#usability-features)
+ [Uploading Files, Folders, Websites, and Arbitrary Data from stdin](#uploading-files--folders--websites--and-arbitrary-data-from-stdin)
- [Files](#files)
- [Folders and Websites](#folders-and-websites)
- [Standard Input](#standard-input)
+ [Custom HTTP Headers](#custom-http-headers)
+ [Autocomplete](#autocomplete)
+ [Numerical Separator and Units](#numerical-separator-and-units)
+ [Stamp Picker](#stamp-picker)
+ [Identity Picker](#identity-picker)
+ [Human Readable Topics](#human-readable-topics)
+ [Manifest address scheme](#manifest-address-scheme)
+ [Automating tasks with Swarm-CLI](#automating-tasks-with-swarm-cli)
- [Connectivity](#connectivity)
- [Postage Stamps](#postage-stamps)
- [Uploading](#uploading)
* [Config](#config)
* [Assignment priority](#assignment-priority)
* [System environment](#system-environment)
- [Development](#development)
- [Contribute](#contribute)
- [Maintainers](#maintainers)
- [License](#license)

# Demo

Expand Down Expand Up @@ -157,6 +162,68 @@ This URL will stay the same when we upload an updated version of the website. Be

## Usability Features

### Uploading Files, Folders, Websites, and Arbitrary Data from stdin

#### Files

Use `swarm-cli` to upload a single file:

```
swarm-cli upload README.md
```

The command above will print a `/bzz` URL that may be opened in the browser. If the browser is able to handle the file format then the file is displayed, otherwise it will be offered to be downloaded.

#### Folders and Websites

`swarm-cli` also supports uploading folders with the same `upload` command:

```
swarm-cli upload build/
```

This also yields a `/bzz` URL. If there is an `index.html` present in the root of the folder, `--index-document` will be automatically applied by `swarm-cli`. This option sets which file the browser should open for an empty path. You may also freely set `--index-document` during upload to change this.

#### Standard Input

You can pipe data from other commands to `swarm-cli` using the `--stdin` option.

```
curl -L https://picsum.photos/200 | swarm-cli --stdin --stamp [...]
```

Unlike other upload methods, this results in a `/bytes` URL, which cannot be displayed by browsers normally. You can still share your hash and others can download it. However, with the `--name` option, you can give your arbitrary data a file name, and `swarm-cli` will attempt to determine the suitable content type for your data. Given it is successful, `swarm-cli` will print a `/bzz` URL instead of the `/bytes` URL, which is good to be displayed in browsers. Example:

```
curl -L https://picsum.photos/200 | swarm-cli --stdin --stamp [...] --name random.jpg
```

There is also a `--content-type` option if you want to adjust it manually:

```
curl -L https://picsum.photos/200 | swarm-cli --stdin --stamp [...] --name random --content-type image/jpeg
```

Please note that stdin is reserved for the data you are uploading, so interactive features are disabled during this time. Because of that, `--stamp` must be passed beforehand. You may create an alias for grabbing the ID of the least used postage stamp:

```
alias st='swarm-cli stamp list --least-used --limit 1 --hide-usage --quiet'
```

Leveraging the alias above, you can use a shortcut for uploading from stdin:

```
curl -L https://picsum.photos/200 | swarm-cli --stdin --stamp $(st)
```

### Custom HTTP Headers

Similarly to `curl`, you may use the `--header` or `-H` option to specify as many additional headers as you want, which will be sent with all requests:

```
swarm-cli upload README.md -H "Authorization: [...]" -H "X-Custom-Header: Your Value"
```

### Autocomplete

`swarm-cli` has support for autocomplete in `bash`, `zsh` and `fish`. This turns on `<tab><tab>` suggestions which can complete commands, paths and options for you.
Expand Down Expand Up @@ -307,27 +374,33 @@ swarm-cli status -q | head -n 1 | grep "^OK"
Grab the first postage stamp:

```
swarm-cli stamp list --limit 1 -q | awk '{ print $1 }'
swarm-cli stamp list --limit 1 --quiet --hide-usage
```

Grab the least used postage stamp:

```
swarm-cli stamp list --limit 1 --quiet --hide-usage --least-used
```

List all postage stamps with zero utilization:

```
swarm-cli stamp list --max-usage 0 -q | awk '{ print $1 }'
swarm-cli stamp list --max-usage 0 --quiet --hide-usage
```

Sort postage stamps based on utilization (least utilized comes first):

```
swarm-cli stamp list --least-used -q
swarm-cli stamp list --least-used --quiet
```

#### Uploading

Upload a file with the least utilized postage stamp (that has at most 50% usage):

```
STAMP=$(swarm-cli stamp list --max-usage 50 --least-used --limit 1 -q | awk '{ print $1 }')
STAMP=$(swarm-cli stamp list --max-usage 50 --least-used --limit 1 --quiet --hide-usage)
swarm-cli upload -q README.md --stamp $STAMP
```

Expand Down
38 changes: 19 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"chalk": "^2.4.2",
"cli-progress": "^3.8.2",
"ethereumjs-wallet": "^1.0.1",
"furious-commander": "1.5.0",
"furious-commander": "^1.7.0",
"inquirer": "^7.3.3",
"mantaray-js": "^1.0.3",
"ora": "^5.3.0"
Expand Down
1 change: 1 addition & 0 deletions src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export const application: Application = {
command: 'swarm-cli',
description: 'Manage your Bee node and interact with the Swarm network via the CLI',
version: PackageJson.version,
autocompletion: 'fromOption',
}
19 changes: 16 additions & 3 deletions src/command/root-command/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Bee, BeeDebug } from '@ethersphere/bee-js'
import { Bee, BeeDebug, BeeOptions } from '@ethersphere/bee-js'
import { ExternalOption, Sourcemap, Utils } from 'furious-commander'
import { exit } from 'process'
import { printCurlCommand } from '../../curl'
import { parseHeaders } from '../../utils'
import { ConfigOption } from '../../utils/types/config-option'
import { CommandConfig, CONFIG_OPTIONS } from './command-config'
import { CommandLog, VerbosityLevel } from './command-log'
Expand Down Expand Up @@ -31,6 +32,9 @@ export class RootCommand {
@ExternalOption('curl')
public curl!: boolean

@ExternalOption('header')
public header!: string[]

public bee!: Bee
public _beeDebug!: BeeDebug
public console!: CommandLog
Expand Down Expand Up @@ -83,8 +87,17 @@ export class RootCommand {
this.maybeSetFromConfig(option)
})

this.bee = new Bee(this.beeApiUrl, this.curl ? { onRequest: printCurlCommand } : {})
this._beeDebug = new BeeDebug(this.beeDebugApiUrl, this.curl ? { onRequest: printCurlCommand } : {})
const beeOptions: BeeOptions = {}

if (this.curl) {
beeOptions.onRequest = printCurlCommand
}

if (this.header.length) {
beeOptions.defaultHeaders = parseHeaders(this.header)
}
this.bee = new Bee(this.beeApiUrl, beeOptions)
this._beeDebug = new BeeDebug(this.beeDebugApiUrl, beeOptions)
this.verbosity = VerbosityLevel.Normal

if (this.quiet) {
Expand Down
13 changes: 12 additions & 1 deletion src/command/stamp/list.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { LeafCommand, Option } from 'furious-commander'
import { exit } from 'process'
import { enrichStamp, printStamp } from '../../service/stamp'
import { EnrichedStamp } from '../../service/stamp/types/stamp'
import { printDivided } from '../../utils/text'
import { CommandLog } from '../root-command/command-log'
import { StampCommand } from './stamp-command'

export class List extends StampCommand implements LeafCommand {
Expand All @@ -17,6 +19,9 @@ export class List extends StampCommand implements LeafCommand {
@Option({ key: 'limit', type: 'number', minimum: 1, description: 'Limit the amount of printed stamps' })
public limit!: number

@Option({ key: 'hide-usage', type: 'boolean', description: 'Do not print usage percentage' })
public hideUsage!: boolean

@Option({
key: 'max-usage',
type: 'number',
Expand Down Expand Up @@ -60,6 +65,12 @@ export class List extends StampCommand implements LeafCommand {

const orderedStamps = this.leastUsed ? limitedStamps.sort((a, b) => a.usage - b.usage) : limitedStamps

printDivided(orderedStamps, printStamp, this.console)
printDivided(
orderedStamps,
(items: EnrichedStamp, console: CommandLog) => {
printStamp(items, console, !this.hideUsage)
},
this.console,
)
}
}
Loading

0 comments on commit 42ae5da

Please sign in to comment.