upload command. profile no more. long live the session...

This commit is contained in:
educative 2021-11-21 02:19:45 +01:00
parent 07d125e674
commit 18c4fc7c4c
9 changed files with 176 additions and 91 deletions

View File

@ -20,27 +20,38 @@ root directory of the local Calibre library. For search (authors, titles,
tags...) it uses rendered metadata from static/data{1-8}.js files.
Every time the directory path and/or librarian is provided it is saved in
the configuration file for the future use (therefore: 'accorder build PROFILE'
the configuration file for the future use (therefore: 'accorder build SESSION'
should be enough for the next successful build).`,
Args: OnlyProfileArgument,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
calibrePath := viper.GetString(fmt.Sprintf("%s.calibre_path", args[0]))
librarianName := viper.GetString(fmt.Sprintf("%s.librarian_name", args[0]))
libraryUUID := viper.GetString(fmt.Sprintf("%s.library_uuid", args[0]))
librarySecret := viper.GetString(fmt.Sprintf("%s.library_secret", args[0]))
session := args[0]
libraryUUID := viper.GetString(fmt.Sprintf("%s.library_uuid", session))
librarySecret := viper.GetString(fmt.Sprintf("%s.library_secret", session))
calibrePathFromCli, _ := cmd.PersistentFlags().GetString("directory")
librarianNameFromCli, _ := cmd.PersistentFlags().GetString("librarian")
if calibrePathFromCli != "" || librarianNameFromCli != "" || libraryUUID == "" || librarySecret == "" {
// didn't exist before
if libraryUUID == "" {
// new session provided path + librarian name
if calibrePathFromCli != "" && librarianNameFromCli != "" {
libraryUUID = uuid.NewV4().String()
viper.Set(fmt.Sprintf("%s.library_uuid", args[0]), libraryUUID)
} else if librarySecret == "" {
librarySecret = uuid.NewV4().String()
viper.Set(fmt.Sprintf("%s.library_secret", args[0]), librarySecret)
viper.WriteConfig()
fmt.Printf("Added new session `%s` to the config file.\nNext time it is enough to run:\naccorder build %s\nand it will be run with the same settings.", session, session)
} else {
fmt.Printf("Adding new SESSION via `upload` command should have both: \n librarian name and Calibre path \nto be run and automatically added to the config file. For example:\naccorder build -d \"/users/jessica/Calibre library/\" -l \"Aaron Elbakyan\" %s", session)
os.Exit(1)
}
} else if calibrePathFromCli != "" || librarianNameFromCli != "" {
viper.WriteConfig()
}
calibrePath := viper.GetString(fmt.Sprintf("%s.local_upload", args[0]))
librarianName := viper.GetString(fmt.Sprintf("%s.librarian_name", args[0]))
jsonPath, _ := cmd.PersistentFlags().GetString("jsonpath")
calibre.RenderStandaloneApp(calibrePath, librarianName, libraryUUID, librarySecret, jsonPath)
},
@ -52,8 +63,8 @@ func init() {
buildCmd.PersistentFlags().StringP("jsonpath", "j", "", "Path where to render all metadata into JSON.")
buildCmd.PersistentFlags().StringP("bibtex", "b", "", "Import books from BibTex file into Calibre.")
CustomHelpOutput(buildCmd)
profile := os.Args[len(os.Args)-1]
viper.BindPFlag(fmt.Sprintf("%s.calibre_path", profile), buildCmd.PersistentFlags().Lookup("directory"))
viper.BindPFlag(fmt.Sprintf("%s.librarian_name", profile), buildCmd.PersistentFlags().Lookup("librarian"))
session := os.Args[len(os.Args)-1]
viper.BindPFlag(fmt.Sprintf("%s.local_upload", session), buildCmd.PersistentFlags().Lookup("directory"))
viper.BindPFlag(fmt.Sprintf("%s.librarian_name", session), buildCmd.PersistentFlags().Lookup("librarian"))
rootCmd.AddCommand(buildCmd)
}

View File

@ -1,9 +1,11 @@
package cmd
import (
"encoding/json"
"fmt"
"github.com/kirsle/configdir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"os"
"path/filepath"
)
@ -14,14 +16,37 @@ func CustomHelpOutput(cmd *cobra.Command) {
cmd.SetUsageTemplate(UsageTemplate)
}
func OnlyProfileArgument(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("Please, provide PROFILE as the last argument.")
func ViperSettingsPrint() {
vipAll, err := json.MarshalIndent(viper.AllSettings(), "", " ")
if err != nil {
fmt.Println("error:", err)
}
if len(args) > 1 {
return fmt.Errorf("You can only have one argument and that should be PROFILE.")
fmt.Print(string(vipAll))
}
func CliFlagValue(cmd *cobra.Command, key string) (value string) {
value, _ = cmd.PersistentFlags().GetString(key)
return
}
func ViperValue(session, key string) string {
return viper.GetString(fmt.Sprintf("%s.%s", session, key))
}
func CheckProfile(cmd *cobra.Command, args []string) error {
hasProfile := false
// fmt.Println("VIPER:", viper.AllSettings())
for k, v := range viper.AllSettings() {
fmt.Println("VIPER KEY/VALUE:", k, v)
if k == args[0] {
hasProfile = true
}
return nil
}
if !hasProfile {
return fmt.Errorf("PROFILE %s should be added to the configuration file.\n", args[0])
}
return fmt.Errorf("MEH! %s should be added to the configuration file.\n", args[0])
}
func ConfigBaseDir() string {

30
cmd/mc.go Normal file
View File

@ -0,0 +1,30 @@
/*
Copyright © 2021
*/
package cmd
import (
miniocmd "github.com/minio/mc/cmd"
"github.com/spf13/cobra"
"os"
)
// mcCmd represents the mc command
var mcCmd = &cobra.Command{
Use: "mc",
Short: "A proxy for `mc` minio client responsible for upload & download`.",
Run: func(cmd *cobra.Command, args []string) {
// rgs := []string{"", "-C", ConfigMinioDir()}
// rgs := []string{"", "-C", ConfigMinioDir()}
os.Setenv("MC_HOST_minio.memoryoftheworld.org", "https://klemo:U9@?x$)Kdoq15)J~@minio.memoryoftheworld.org")
rgs := []string{"", "-C", ConfigMinioDir(), "ls", "minio.memoryoftheworld.org/klemo"}
rgs = append(rgs, args...)
miniocmd.Main(rgs)
},
}
func init() {
mcCmd.DisableFlagParsing = true
rootCmd.AddCommand(mcCmd)
}

View File

@ -28,12 +28,16 @@ It helps a librarian to maintain and share her catalog at
https://library.memoryoftheworld.org
together with other amateur librarians.
It does all of above in one go by typing: accorder release PROFILE.
It does all of above in one go by typing: accorder release SESSION.
The configuration file will keep information about one or more PROFILE.
Under every PROFILE's configuration section there will be information
The configuration file will keep information about one or more SESSION.
Good name for SESSION is the one which reminds you quickly on what
SESSION would do.
Under every SESSION's configuration section there will be information
about the directory path of local Calibre's library, librarian's name,
credentials needed to upload the files to the destination server etc.`,
credentials needed to upload/download the files to the destination
server etc.`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := initConfig(args); err != nil {
fmt.Println("ERROR:", err)
@ -65,22 +69,12 @@ func initConfig(args []string) error {
viper.AddConfigPath(ConfigBaseDir())
viper.SetConfigName("config")
viper.AutomaticEnv() // read in environment variables that match
// viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err != nil {
fmt.Println("ERROR:", err, "with config:", viper.ConfigFileUsed())
os.Exit(1)
return fmt.Errorf("ERROR:%s with config:%s", err, viper.ConfigFileUsed())
}
hasProfile := false
for k := range viper.AllSettings() {
if k == args[0] {
hasProfile = true
}
}
if !hasProfile {
return fmt.Errorf("PROFILE %s should be added to the configuration file.\n", args[0])
}
return nil
}

View File

@ -12,7 +12,7 @@ var submitCmd = &cobra.Command{
Short: "Submit metadata to the aggregated MotW Library.",
Long: `Submit all the library's metadata to the aggregated Memory of the World
Library (https://library.memoryoftheworld.org).`,
Args: OnlyProfileArgument,
// Args: OnlyProfileArgument,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(args)
},

View File

@ -5,8 +5,8 @@ import (
"os"
miniocmd "github.com/minio/mc/cmd"
"github.com/satori/go.uuid"
"github.com/spf13/cobra"
// "github.com/spf13/pflag"
"github.com/spf13/viper"
)
@ -19,68 +19,90 @@ It will take care of the differences so files already at the server
will not be uploaded again.
Every time the directory path and/or librarian is provided it is saved in
configuration file for the future use (therefore: 'accorder upload PROFILE'
configuration file for the future use (therefore: 'accorder upload SESSION'
should be enough for the next successful upload).`,
Args: OnlyProfileArgument,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
// calibrePath := viper.GetString(fmt.Sprintf("%s.calibre_path", args[0]))
// librarianName := viper.GetString(fmt.Sprintf("%s.librarian_name", args[0]))
profile := args[0]
libraryUUID := viper.GetString(fmt.Sprintf("%s.library_uuid", profile))
librarySecret := viper.GetString(fmt.Sprintf("%s.library_secret", profile))
session := args[0]
calibrePathFromCli, _ := cmd.PersistentFlags().GetString("directory")
librarianNameFromCli, _ := cmd.PersistentFlags().GetString("librarian")
uploadBucketFromCli, _ := cmd.PersistentFlags().GetString("bucket")
if calibrePathFromCli != "" || librarianNameFromCli != "" || uploadBucketFromCli != "" || libraryUUID == "" || librarySecret == "" {
if libraryUUID == "" {
libraryUUID = uuid.NewV4().String()
viper.Set(fmt.Sprintf("%s.library_uuid", profile), libraryUUID)
} else if librarySecret == "" {
librarySecret = uuid.NewV4().String()
viper.Set(fmt.Sprintf("%s.library_secret", profile), librarySecret)
server := ViperValue(session, "server_upload")
// username in upload context comes from library_uuid
username := ViperValue(session, "library_uuid")
// password in upload context comes from library_secret
password := ViperValue(session, "library_secret")
bucket := ViperValue(session, "bucket_upload")
localDirectory := ViperValue(session, "local_upload")
exit := false
for vipFlag, cliFlag := range map[string]string{
"server_upload": "server",
"library_uuid": "username",
"library_secret": "password",
"bucket_upload": "bucket",
"local_upload": "directory",
} {
if ViperValue(session, vipFlag) == "" {
fmt.Printf("ERROR: A flag --%s is missing for session `%s` to work.\n", cliFlag, session)
exit = true
}
}
if exit {
fmt.Println("~ ~ ~ ~")
cmd.Usage()
os.Exit(1)
}
if cmd.Flags().NFlag() > 0 {
viper.WriteConfig()
}
deleteResidue, _ := cmd.PersistentFlags().GetBool("delete-residue")
rgs := []string{}
deleteResidue, _ := cmd.PersistentFlags().GetBool("delete-residue")
verbose, _ := cmd.PersistentFlags().GetBool("verbose")
os.Setenv(
fmt.Sprintf("MC_HOST_%s", server),
fmt.Sprintf("https://%s:%s@%s", username, password, server),
)
rgs := []string{"",
"-C", ConfigMinioDir(),
"mirror", "--overwrite",
}
if deleteResidue {
rgs = []string{"",
"-C", ConfigMinioDir(),
"mirror",
// "--fake",
"--overwrite",
"--remove",
viper.GetString(fmt.Sprintf("%s.calibre_path", profile)),
fmt.Sprintf("%s.upload/%s/", profile, viper.GetString(fmt.Sprintf("%s.bucket_upload", profile))),
}
} else {
rgs = []string{"",
"-C", ConfigMinioDir(),
"mirror",
// "--fake",
"--overwrite",
viper.GetString(fmt.Sprintf("%s.calibre_path", profile)),
fmt.Sprintf("%s.upload/%s/", profile, viper.GetString(fmt.Sprintf("%s.bucket_upload", profile))),
rgs = append(rgs, "--remove")
}
if verbose {
rgs = append(rgs, "--json")
}
rgs = append(rgs, localDirectory, fmt.Sprintf("%s/%s", server, bucket))
miniocmd.Main(rgs)
},
}
func init() {
rootCmd.AddCommand(uploadCmd)
uploadCmd.PersistentFlags().StringP("directory", "d", "", "A local Calibre directory path.")
uploadCmd.PersistentFlags().StringP("bucket", "b", "", "A minio bucket where to upload.")
uploadCmd.PersistentFlags().StringP("librarian", "l", "", "Librarian's name.")
uploadCmd.PersistentFlags().StringP("directory", "d", "", "A local directory to be uploaded.")
uploadCmd.PersistentFlags().StringP("username", "u", "", "Username.")
uploadCmd.PersistentFlags().StringP("password", "p", "", "Password.")
uploadCmd.PersistentFlags().StringP("bucket", "b", "", "A remote directory/bucket where to upload.")
uploadCmd.PersistentFlags().StringP("server", "s", "", "Server.")
uploadCmd.PersistentFlags().BoolP("delete-residue", "", false, "Delete any remote files not present locally anymore.")
uploadCmd.PersistentFlags().BoolP("verbose", "v", false, "Verbose log.")
CustomHelpOutput(uploadCmd)
profile := os.Args[len(os.Args)-1]
viper.BindPFlag(fmt.Sprintf("%s.calibre_path", profile), buildCmd.PersistentFlags().Lookup("directory"))
viper.BindPFlag(fmt.Sprintf("%s.librarian_name", profile), buildCmd.PersistentFlags().Lookup("librarian"))
viper.BindPFlag(fmt.Sprintf("%s.bucket_upload", profile), buildCmd.PersistentFlags().Lookup("bucket"))
rootCmd.AddCommand(buildCmd)
session := os.Args[len(os.Args)-1]
for vipFlag, cliFlag := range map[string]string{
"server_upload": "server",
"library_uuid": "username",
"library_secret": "password",
"bucket_upload": "bucket",
"local_upload": "directory",
} {
viper.BindPFlag(fmt.Sprintf("%s.%s", session, vipFlag), uploadCmd.PersistentFlags().Lookup(cliFlag))
}
}

5
go.mod
View File

@ -4,9 +4,8 @@ go 1.16
require (
github.com/karrick/godirwalk v1.16.1
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f // indirect
github.com/minio/mc v0.0.0-20211116163708-d0c62eb584e5 // indirect
github.com/mitchellh/go-homedir v1.1.0
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f
github.com/minio/mc v0.0.0-20211116163708-d0c62eb584e5
github.com/satori/go.uuid v1.2.0
github.com/spf13/cobra v1.2.1
github.com/spf13/viper v1.9.0

13
go.sum
View File

@ -59,6 +59,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@ -191,6 +192,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@ -220,6 +222,7 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
@ -293,11 +296,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lestrrat-go/backoff/v2 v2.0.7/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
@ -396,6 +398,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
@ -542,6 +545,7 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
@ -746,7 +750,6 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -761,7 +764,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
@ -830,6 +832,7 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@ -965,8 +968,8 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/h2non/filetype.v1 v1.0.5 h1:CC1jjJjoEhNVbMhXYalmGBhOBK2V70Q1N850wt/98/Y=

View File

@ -422,4 +422,5 @@ func RenderStandaloneApp(calibrePath, librarianName, libraryUUID, librarySecret,
err = os.WriteFile(jsonPath, jsonDump, 0666)
c(err, "writing json file failed...")
}
fmt.Printf("Check out: %sBROWSE_LIBRARY.html", calibrePath)
}