checkpoint: add configuration
This commit is contained in:
parent
632a620180
commit
f451ed22c3
6 changed files with 138 additions and 35 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
"os"
|
||||
"strconv"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/executor"
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
|
||||
)
|
||||
|
@ -30,21 +31,10 @@ func main() {
|
|||
func run() error {
|
||||
var (
|
||||
configDir string
|
||||
cacheDir string
|
||||
pager string
|
||||
imageViewer string
|
||||
videoPlayer string
|
||||
maxTerminalWidth int
|
||||
noColor *bool
|
||||
)
|
||||
|
||||
flag.StringVar(&configDir, "config-dir", "", "Specify your config directory")
|
||||
flag.StringVar(&cacheDir, "cache-dir", "", "Specify your cache directory")
|
||||
flag.StringVar(&pager, "pager", "", "Specify your preferred pager to page through long outputs. This is disabled by default.")
|
||||
flag.StringVar(&imageViewer, "image-viewer", "", "Specify your favourite image viewer.")
|
||||
flag.StringVar(&videoPlayer, "video-player", "", "Specify your favourite video player.")
|
||||
flag.IntVar(&maxTerminalWidth, "max-terminal-width", 80, "Specify the maximum terminal width when displaying resources on screen.")
|
||||
|
||||
flag.BoolFunc("no-color", "Disable ANSI colour output when displaying text on screen", func(value string) error {
|
||||
boolVal, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
|
@ -80,7 +70,15 @@ func run() error {
|
|||
command := flag.Arg(0)
|
||||
args := flag.Args()[1:]
|
||||
|
||||
printer := printer.NewPrinter(*noColor, pager, maxTerminalWidth)
|
||||
config, err := config.NewConfigFromFile(configDir)
|
||||
if err != nil {
|
||||
printer := printer.NewPrinter(*noColor, "", 80)
|
||||
printer.PrintFailure("unable to load the configuration: " + err.Error() + ".")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
printer := printer.NewPrinter(*noColor, config.Integrations.Pager, config.LineWrapMaxWidth)
|
||||
|
||||
executorMap := map[string]executor.Executor{
|
||||
executor.CommandAccept: executor.NewAcceptOrRejectExecutor(
|
||||
|
@ -175,10 +173,8 @@ func run() error {
|
|||
),
|
||||
executor.CommandShow: executor.NewShowExecutor(
|
||||
printer,
|
||||
&config,
|
||||
configDir,
|
||||
cacheDir,
|
||||
imageViewer,
|
||||
videoPlayer,
|
||||
executor.CommandShow,
|
||||
executor.CommandSummaryLookup(executor.CommandShow),
|
||||
),
|
||||
|
|
103
internal/config/config.go
Normal file
103
internal/config/config.go
Normal file
|
@ -0,0 +1,103 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
|
||||
)
|
||||
|
||||
const (
|
||||
configFileName = "config.json"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CacheDirectory string `json:"cacheDirectory"`
|
||||
LineWrapMaxWidth int `json:"lineWrapMaxWidth"`
|
||||
HTTP HTTPConfig `json:"http"`
|
||||
Integrations Integrations `json:"integrations"`
|
||||
}
|
||||
|
||||
type HTTPConfig struct {
|
||||
Timeout int `json:"timeout"`
|
||||
MediaTimeout int `json:"mediaTimeout"`
|
||||
}
|
||||
|
||||
type Integrations struct {
|
||||
Browser string `json:"browser"`
|
||||
Editor string `json:"editor"`
|
||||
Pager string `json:"pager"`
|
||||
ImageViewer string `json:"imageViewer"`
|
||||
VideoPlayer string `json:"videoPlayer"`
|
||||
}
|
||||
|
||||
func NewConfigFromFile(configDir string) (Config, error) {
|
||||
path := configFile(configDir)
|
||||
|
||||
fileExists, err := utilities.FileExists(path)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("unable to check if the config file exists: %w", err)
|
||||
}
|
||||
|
||||
if !fileExists {
|
||||
if err := saveDefaultConfigToFile(path); err != nil {
|
||||
return Config{}, fmt.Errorf("unable to save the default config to file: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("unable to open %s: %w", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var config Config
|
||||
|
||||
if err := json.NewDecoder(file).Decode(&config); err != nil {
|
||||
return Config{}, fmt.Errorf("unable to decode the JSON data: %w", err)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func configFile(configDir string) string {
|
||||
return filepath.Join(utilities.CalculateConfigDir(configDir), configFileName)
|
||||
}
|
||||
|
||||
func saveDefaultConfigToFile(path string) error {
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create the file at %s: %w", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
config := defaultConfig()
|
||||
encoder := json.NewEncoder(file)
|
||||
encoder.SetIndent("", " ")
|
||||
|
||||
if err := encoder.Encode(config); err != nil {
|
||||
return fmt.Errorf("unable to save the JSON data to the config file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultConfig() Config {
|
||||
return Config{
|
||||
CacheDirectory: "",
|
||||
HTTP: HTTPConfig{
|
||||
Timeout: 5,
|
||||
MediaTimeout: 30,
|
||||
},
|
||||
LineWrapMaxWidth: 80,
|
||||
Integrations: Integrations{
|
||||
Browser: "",
|
||||
Editor: "",
|
||||
Pager: "",
|
||||
ImageViewer: "",
|
||||
VideoPlayer: "",
|
||||
},
|
||||
}
|
||||
}
|
|
@ -109,7 +109,7 @@ func NewCredentialsConfigFromFile(configDir string) (CredentialsConfig, error) {
|
|||
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return CredentialsConfig{}, fmt.Errorf("unable to open %s, %w", path, err)
|
||||
return CredentialsConfig{}, fmt.Errorf("unable to open %s: %w", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
@ -127,9 +127,8 @@ func saveCredentialsConfigFile(authConfig CredentialsConfig, configDir string) e
|
|||
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open %s: %w", path, err)
|
||||
return fmt.Errorf("unable to create the file at %s: %w", path, err)
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
encoder := json.NewEncoder(file)
|
||||
|
|
|
@ -102,3 +102,11 @@ type NotFollowingError struct {
|
|||
func (e NotFollowingError) Error() string {
|
||||
return "you are not following " + e.Account
|
||||
}
|
||||
|
||||
type UnknownMediaAttachmentError struct {
|
||||
AttachmentID string
|
||||
}
|
||||
|
||||
func (e UnknownMediaAttachmentError) Error() string {
|
||||
return "unknown media attachment '" + e.AttachmentID + "'"
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/printer"
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
|
||||
|
@ -20,12 +21,12 @@ type ShowExecutor struct {
|
|||
*flag.FlagSet
|
||||
|
||||
printer *printer.Printer
|
||||
config *config.Config
|
||||
myAccount bool
|
||||
skipAccountRelationship bool
|
||||
showUserPreferences bool
|
||||
showInBrowser bool
|
||||
configDir string
|
||||
cacheRoot string
|
||||
resourceType string
|
||||
accountName string
|
||||
statusID string
|
||||
|
@ -34,21 +35,17 @@ type ShowExecutor struct {
|
|||
tag string
|
||||
pollID string
|
||||
fromResourceType string
|
||||
imageViewer string
|
||||
videoPlayer string
|
||||
limit int
|
||||
attachmentIDs MultiStringFlagValue
|
||||
}
|
||||
|
||||
func NewShowExecutor(printer *printer.Printer, configDir, cacheRoot, imageViewer, videoPlayer, name, summary string) *ShowExecutor {
|
||||
func NewShowExecutor(printer *printer.Printer, config *config.Config, configDir, name, summary string) *ShowExecutor {
|
||||
showExe := ShowExecutor{
|
||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||
|
||||
printer: printer,
|
||||
config: config,
|
||||
configDir: configDir,
|
||||
cacheRoot: cacheRoot,
|
||||
imageViewer: imageViewer,
|
||||
videoPlayer: videoPlayer,
|
||||
}
|
||||
|
||||
showExe.BoolVar(&showExe.myAccount, flagMyAccount, false, "Set to true to lookup your account")
|
||||
|
@ -471,7 +468,7 @@ func (s *ShowExecutor) showMediaFromStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
cacheDir := filepath.Join(
|
||||
utilities.CalculateCacheDir(s.cacheRoot, utilities.GetFQDN(gtsClient.Authentication.Instance)),
|
||||
utilities.CalculateCacheDir(s.config.CacheDirectory, utilities.GetFQDN(gtsClient.Authentication.Instance)),
|
||||
"media",
|
||||
)
|
||||
|
||||
|
@ -498,7 +495,7 @@ func (s *ShowExecutor) showMediaFromStatus(gtsClient *client.Client) error {
|
|||
for _, attachmentID := range s.attachmentIDs {
|
||||
mediaObj, ok := attachmentsHashMap[attachmentID]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown media attachment: %s", attachmentID)
|
||||
return UnknownMediaAttachmentError{AttachmentID: attachmentID}
|
||||
}
|
||||
|
||||
split := strings.Split(mediaObj.url, "/")
|
||||
|
@ -533,13 +530,13 @@ func (s *ShowExecutor) showMediaFromStatus(gtsClient *client.Client) error {
|
|||
}
|
||||
|
||||
if len(imageFiles) > 0 {
|
||||
if err := utilities.OpenMedia(s.imageViewer, imageFiles); err != nil {
|
||||
if err := utilities.OpenMedia(s.config.Integrations.ImageViewer, imageFiles); err != nil {
|
||||
return fmt.Errorf("unable to open the image viewer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(videoFiles) > 0 {
|
||||
if err := utilities.OpenMedia(s.videoPlayer, videoFiles); err != nil {
|
||||
if err := utilities.OpenMedia(s.config.Integrations.VideoPlayer, videoFiles); err != nil {
|
||||
return fmt.Errorf("unable to open the video player: %w", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ func CalculateConfigDir(configDir string) string {
|
|||
|
||||
configRoot, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
configRoot = "."
|
||||
return filepath.Join(os.Getenv("HOME"), "."+internal.ApplicationName, "config")
|
||||
}
|
||||
|
||||
return filepath.Join(configRoot, internal.ApplicationName)
|
||||
|
@ -33,7 +33,7 @@ func CalculateCacheDir(cacheDir, instanceFQDN string) string {
|
|||
|
||||
cacheRoot, err := os.UserCacheDir()
|
||||
if err != nil {
|
||||
cacheRoot = "."
|
||||
return filepath.Join(os.Getenv("HOME"), "."+internal.ApplicationName, "cache")
|
||||
}
|
||||
|
||||
return filepath.Join(cacheRoot, internal.ApplicationName, instanceFQDN)
|
||||
|
|
Loading…
Reference in a new issue