Initial Commit
This commit is contained in:
87
cmd/covergen/main.go
Normal file
87
cmd/covergen/main.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"covergen/pkg/covergen"
|
||||
)
|
||||
|
||||
var colors = []string{"red", "blue", "yellow", "green"}
|
||||
var colorMap = map[string]covergen.Color{
|
||||
"red": {255, 85, 0},
|
||||
"blue": {59, 180, 255},
|
||||
"yellow": {255, 230, 0},
|
||||
"green": {76, 177, 110},
|
||||
}
|
||||
|
||||
var number = pflag.StringP("number", "n", "", "Invoice or quotation number")
|
||||
var customer = pflag.StringP("customer", "c", "", "Customer name for cover")
|
||||
var numberPrefix = pflag.String("number-prefix", "offerte", "Prefix to use for number")
|
||||
var color = pflag.String("color", "random", "Selects a color to use for the grid highlight. Valid choices: ['random', 'red', 'blue', 'yellow', 'green']")
|
||||
var output = pflag.StringP("output", "o", "cover.pdf", "File to output to")
|
||||
|
||||
func init() {
|
||||
log.Logger = zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).With().Timestamp().Logger()
|
||||
pflag.Parse()
|
||||
|
||||
if *number == "" {
|
||||
log.Error().Msg("Missing (invoice) number flag")
|
||||
pflag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *customer == "" {
|
||||
log.Error().Msg("Missing customer name flag")
|
||||
pflag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *color != "random" {
|
||||
if _, ok := colorMap[*color]; !ok {
|
||||
log.Error().Msgf("Color %s is not defined", *color)
|
||||
pflag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if *output == "" {
|
||||
log.Error().Msg("Invalid output flag")
|
||||
pflag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
var chosenColor covergen.Color
|
||||
if *color == "random" {
|
||||
chosenColor = colorMap[colors[rand.Intn(len(colors))]]
|
||||
} else {
|
||||
chosenColor = colorMap[*color]
|
||||
}
|
||||
|
||||
*customer = strings.ReplaceAll(*customer, "\\n", "\n")
|
||||
|
||||
pdf, err := covergen.GenerateInvoice(covergen.CoverSettings{
|
||||
Number: *number,
|
||||
NumberPrefix: *numberPrefix,
|
||||
CustomerName: *customer,
|
||||
HLColor: chosenColor,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to render invoice")
|
||||
}
|
||||
|
||||
if err := pdf.OutputFileAndClose(*output); err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to write invoice to disk")
|
||||
}
|
||||
}
|
||||
14
cmd/server/main.go
Normal file
14
cmd/server/main.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := http.ListenAndServe(":9090", http.FileServer(http.Dir("assets")))
|
||||
if err != nil {
|
||||
fmt.Println("Failed to start server", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
118
cmd/wasm/main.go
Normal file
118
cmd/wasm/main.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall/js"
|
||||
|
||||
"github.com/thegrumpylion/jsref"
|
||||
|
||||
"covergen/pkg/covergen"
|
||||
)
|
||||
|
||||
type jsmap = map[string]interface{}
|
||||
|
||||
type covergenArgs struct {
|
||||
Customer string `jsref:"customer"`
|
||||
Number string `jsref:"number"`
|
||||
NumberPrefix string `jsref:"numberPrefix"`
|
||||
HLColor string `jsref:"hlColor"`
|
||||
}
|
||||
|
||||
func parseHexColor(s string) (c covergen.Color, err error) {
|
||||
switch len(s) {
|
||||
case 7:
|
||||
_, err = fmt.Sscanf(s, "#%02x%02x%02x", &c.R, &c.G, &c.B)
|
||||
case 4:
|
||||
_, err = fmt.Sscanf(s, "#%1x%1x%1x", &c.R, &c.G, &c.B)
|
||||
// Double the hex digits:
|
||||
c.R *= 17
|
||||
c.G *= 17
|
||||
c.B *= 17
|
||||
default:
|
||||
err = fmt.Errorf("invalid length, must be 7 or 4")
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func settingsFromValue(arg js.Value) (*covergen.CoverSettings, error) {
|
||||
settings := covergenArgs{
|
||||
NumberPrefix: "offerte",
|
||||
}
|
||||
err := jsref.Unmarshal(&settings, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if settings.Number == "" {
|
||||
return nil, errors.New("number: shouldn't be empty")
|
||||
}
|
||||
|
||||
if settings.Customer == "" {
|
||||
return nil, errors.New("customer: shouldn't be empty")
|
||||
}
|
||||
|
||||
color := covergen.Color{R: 255}
|
||||
if settings.HLColor != "" {
|
||||
color, err = parseHexColor(settings.HLColor)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("hlColor: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &covergen.CoverSettings{
|
||||
Number: settings.Number,
|
||||
NumberPrefix: settings.NumberPrefix,
|
||||
CustomerName: settings.Customer,
|
||||
HLColor: color,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func generateCover(this js.Value, args []js.Value) interface{} {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Println("recovered", r)
|
||||
}
|
||||
}()
|
||||
|
||||
if len(args) != 1 {
|
||||
return jsmap{"error": "missing argument"}
|
||||
}
|
||||
|
||||
arg := args[0]
|
||||
if arg.Type() != js.TypeObject {
|
||||
return jsmap{"error": "expected object"}
|
||||
}
|
||||
|
||||
settings, err := settingsFromValue(arg)
|
||||
if err != nil {
|
||||
return jsmap{"error": err.Error()}
|
||||
}
|
||||
|
||||
pdf, err := covergen.GenerateInvoice(*settings)
|
||||
if err != nil {
|
||||
return jsmap{"error": err.Error()}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err = pdf.Output(&buf); err != nil {
|
||||
return jsmap{"error": err.Error()}
|
||||
}
|
||||
|
||||
s := buf.Bytes()
|
||||
sum := sha256.Sum256(s)
|
||||
fmt.Println("shasum", hex.EncodeToString(sum[:]))
|
||||
|
||||
ta := js.Global().Get("Uint8Array").New(len(s))
|
||||
js.CopyBytesToJS(ta, s)
|
||||
return ta
|
||||
}
|
||||
|
||||
func main() {
|
||||
js.Global().Set("covergen", js.FuncOf(generateCover))
|
||||
<-make(chan bool)
|
||||
}
|
||||
Reference in New Issue
Block a user