-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): basic CLI application coding
- Loading branch information
Showing
5 changed files
with
282 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
## `qrcode` CLI Application | ||
|
||
The `qrcode` is a command line application that generates QR codes. | ||
|
||
### Usage | ||
|
||
```sh | ||
$ qrcode -h | ||
NAME: | ||
qrcode - qrcode [options] [source text] | ||
|
||
USAGE: | ||
qrcode [global options] command [command options] [arguments...] | ||
|
||
VERSION: | ||
v2.0.0-beta | ||
|
||
DESCRIPTION: | ||
QR code generator | ||
|
||
AUTHOR: | ||
yeqown <[email protected]> | ||
|
||
COMMANDS: | ||
help, h Shows a list of commands or help for one command | ||
|
||
GLOBAL OPTIONS: | ||
--terminal --terminal (default: false) | ||
--output value, -o value --output=<output file> (default: qrcode.jpg) | ||
--block value, -s value --block=<block size> (default: 5) | ||
--borders value, -b value --borders=<borders> (default: 0,0,0,0) | ||
--circle --circle (default: false) | ||
--help, -h show help (default: false) | ||
--version, -v print the version (default: false) | ||
|
||
COPYRIGHT: | ||
Copyright (c) 2018 yeqown | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
``` | ||
|
||
### Examples | ||
|
||
Provides some examples of how to use the `qrcode` command. | ||
|
||
```sh | ||
# Generate a QR code into file as default | ||
qrcode "Hello, World!" | ||
|
||
# Generate a QR code into file with block size and borders (unit: pixel) | ||
qrcode -o qrcode.png -s 20 -b 20,20,20,20 -m "Hello, World!" | ||
|
||
# Generate a QR code into terminal | ||
qrcode --terminal "Hello, World!" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
package main | ||
|
||
import ( | ||
"path/filepath" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/yeqown/go-qrcode/v2" | ||
"github.com/yeqown/go-qrcode/writer/standard" | ||
"github.com/yeqown/go-qrcode/writer/terminal" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/urfave/cli/v2" | ||
) | ||
|
||
var copyright = `Copyright (c) 2018 yeqown | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
` | ||
|
||
func newApp() *cli.App { | ||
app := cli.NewApp() | ||
app.Name = "qrcode" | ||
app.Description = "QR code generator" | ||
app.Version = "v2.0.0-beta" | ||
app.Authors = []*cli.Author{ | ||
{ | ||
Name: "yeqown", | ||
Email: "[email protected]", | ||
}, | ||
} | ||
app.Usage = "qrcode [options] [source text]" | ||
app.Copyright = copyright | ||
app.Flags = prepareFlags() | ||
app.Action = func(c *cli.Context) error { | ||
genCtx := parseGenerateContextFrom(c) | ||
return generate(genCtx) | ||
} | ||
|
||
return app | ||
} | ||
|
||
func generate(ctx *generateContext) error { | ||
qrc, err := qrcode.New(ctx.text) | ||
if err != nil { | ||
return errors.Wrap(err, "generate QRCode failed") | ||
} | ||
|
||
var w qrcode.Writer | ||
|
||
// construct a writer based generateContext | ||
switch ctx.mode { | ||
case writerMode_TERMINAL: | ||
w = terminal.New() | ||
default: | ||
w, err = standard.New(ctx.FOO.output, ctx.FOO.applyOptions()...) | ||
} | ||
if err != nil { | ||
return errors.Wrap(err, "initialize writer failed") | ||
} | ||
|
||
return qrc.Save(w) | ||
} | ||
|
||
type writerMode uint8 | ||
|
||
const ( | ||
_ writerMode = iota | ||
writerMode_FILE | ||
writerMode_TERMINAL | ||
) | ||
|
||
// generateContext generate qrcode from context | ||
type generateContext struct { | ||
text string | ||
mode writerMode | ||
FOO *fileOutputOptions | ||
TOO *terminalOutputOptions | ||
} | ||
|
||
type fileOutputOptions struct { | ||
output string | ||
outputSuffix string | ||
blockSize uint8 | ||
borders [4]int | ||
isCircleShape bool | ||
} | ||
|
||
func (foo fileOutputOptions) applyOptions() []standard.ImageOption { | ||
options := []standard.ImageOption{ | ||
standard.WithQRWidth(foo.blockSize), | ||
standard.WithBorderWidth(foo.borders[:]...), | ||
} | ||
|
||
switch foo.outputSuffix { | ||
case "png": | ||
options = append(options, standard.WithBuiltinImageEncoder(standard.PNG_FORMAT)) | ||
case "jpg", "jpeg": | ||
fallthrough | ||
default: | ||
options = append(options, standard.WithBuiltinImageEncoder(standard.JPEG_FORMAT)) | ||
} | ||
|
||
if foo.isCircleShape { | ||
options = append(options, standard.WithCircleShape()) | ||
} | ||
|
||
return options | ||
} | ||
|
||
type terminalOutputOptions struct{} | ||
|
||
func parseGenerateContextFrom(c *cli.Context) *generateContext { | ||
genCtx := &generateContext{ | ||
text: c.Args().First(), | ||
mode: writerMode_FILE, | ||
FOO: &fileOutputOptions{ | ||
output: c.String("output"), | ||
outputSuffix: strings.TrimPrefix(filepath.Ext(c.String("output")), "."), | ||
blockSize: uint8(c.Uint("block")), | ||
borders: [4]int{}, | ||
isCircleShape: c.Bool("circle"), | ||
}, | ||
TOO: &terminalOutputOptions{}, | ||
} | ||
|
||
// writer mode | ||
if c.Bool("terminal") { | ||
genCtx.mode = writerMode_TERMINAL | ||
} | ||
|
||
// parse borders | ||
borders := c.String("borders") | ||
arr := strings.Split(borders, ",") | ||
if len(arr) != 4 { | ||
panic("invalid borders format, want: uint8,uint8,uint8,uint8") | ||
} | ||
for i, s := range arr { | ||
v, err := strconv.ParseUint(s, 10, 8) | ||
if err != nil { | ||
panic("invalid borders format, want: uint8") | ||
} | ||
genCtx.FOO.borders[i] = int(v) | ||
} | ||
|
||
return genCtx | ||
} | ||
|
||
func prepareFlags() []cli.Flag { | ||
return []cli.Flag{ | ||
&cli.BoolFlag{ | ||
Name: "terminal", | ||
Usage: "--terminal", | ||
Value: false, | ||
DefaultText: "false", | ||
}, | ||
&cli.StringFlag{ | ||
Name: "output", | ||
Aliases: []string{"o"}, | ||
Usage: "--output=<output file>", | ||
Value: "qrcode.jpg", | ||
DefaultText: "qrcode.jpg", | ||
}, | ||
&cli.UintFlag{ | ||
Name: "block", | ||
Aliases: []string{"s"}, | ||
Usage: "--block=<block size>", | ||
Value: 5, | ||
DefaultText: "5", | ||
}, | ||
&cli.StringFlag{ | ||
Name: "borders", | ||
Aliases: []string{"b"}, | ||
Usage: "--borders=<borders>", | ||
Value: "0,0,0,0", | ||
DefaultText: "0,0,0,0", | ||
}, | ||
&cli.BoolFlag{ | ||
Name: "circle", | ||
Usage: "--circle", | ||
Value: false, | ||
DefaultText: "false", | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,28 @@ | ||
module qrcode | ||
module github.com/yeqown/go-qrcode/cmd/qrcode | ||
|
||
go 1.17 | ||
|
||
require ( | ||
github.com/pkg/errors v0.9.1 | ||
github.com/urfave/cli/v2 v2.3.0 | ||
github.com/yeqown/go-qrcode/v2 v2.0.0-beta | ||
github.com/yeqown/go-qrcode/writer/standard v1.0.0-beta | ||
github.com/yeqown/go-qrcode/writer/terminal v1.0.0-beta | ||
) | ||
|
||
require ( | ||
github.com/yeqown/go-qrcode/writer/standard v1.0.0 | ||
github.com/yeqown/go-qrcode/v2 v2.0.0 | ||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect | ||
github.com/fogleman/gg v1.3.0 // indirect | ||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect | ||
github.com/mattn/go-runewidth v0.0.9 // indirect | ||
github.com/nsf/termbox-go v1.1.1 // indirect | ||
github.com/russross/blackfriday/v2 v2.0.1 // indirect | ||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect | ||
github.com/yeqown/reedsolomon v1.0.0 // indirect | ||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect | ||
) | ||
|
||
replace ( | ||
github.com/yeqown/go-qrcode/v2 v2.0.0 => ../../ | ||
github.com/yeqown/go-qrcode/writer/standard v1.0.0 => ../../writer/standard | ||
) | ||
//replace ( | ||
// github.com/yeqown/go-qrcode/v2 v2.0.0 => ../../ | ||
// github.com/yeqown/go-qrcode/writer/standard v1.0.0 => ../../writer/standard | ||
//) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,13 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
|
||
"github.com/yeqown/go-qrcode/v2" | ||
"github.com/yeqown/go-qrcode/writer/standard" | ||
) | ||
|
||
var ( | ||
contentFlag = flag.String("c", "https://github.com/yeqown/go-qrcode", "input your content to encode") | ||
outputFlag = flag.String("o", "./qrcode.jpeg", "output filename") | ||
"os" | ||
) | ||
|
||
func main() { | ||
flag.Parse() | ||
|
||
qrc, err := qrcode.New(*contentFlag) | ||
if err != nil { | ||
fmt.Printf("could not generate QRCode: %v", err) | ||
return | ||
} | ||
|
||
w, err := standard.New(*outputFlag) | ||
if err != nil { | ||
fmt.Printf("standard writer failed: %v", err) | ||
return | ||
} | ||
app := newApp() | ||
|
||
// save file | ||
if err := qrc.Save(w); err != nil { | ||
fmt.Printf("could not save image: %v", err) | ||
if err := app.Run(os.Args); err != nil { | ||
println(err.Error()) | ||
} | ||
} |