Skip to content

Commit

Permalink
Removed jq and jsoncfg dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
mjwhitta committed Nov 14, 2024
1 parent a83ad7f commit 430a64c
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 132 deletions.
125 changes: 94 additions & 31 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,52 @@ package cache

import (
"archive/zip"
"encoding/json"
"io"
"io/fs"
"net/http"
"os"
"path/filepath"
"slices"
"strings"

"github.com/mjwhitta/artty/art"
"github.com/mjwhitta/errors"
"github.com/mjwhitta/jsoncfg"
"github.com/mjwhitta/pathname"
)

// ArtCache is a struct inheriting from jsoncfg.JSONCfg and containing
// a version string.
// ArtCache is a struct containing all pixel art metadata and a
// version string.
type ArtCache struct {
jsoncfg.JSONCfg
version string
Art map[string]ArtMetadata `json:"art"`
file string `json:"-"`
Version string `json:"version"`
}

// ArtMetadata is a struct containing relevant metadata about
// supported pixel art.
type ArtMetadata struct {
File string `json:"file"`
Height int `json:"height"`
Width int `json:"width"`
}

// New will return a new ArtCache struct pointer with the specified
// version.
func New(version string) *ArtCache {
var c *ArtCache = &ArtCache{
*jsoncfg.New(filepath.Join(cacheDir, cacheFile)),
version,
file: filepath.Join(cacheDir, cacheFile),
}
var vers string = c.GetString("version")

// Initialize defaults
_ = c.SetDefault(map[string]any{}, "art")
_ = c.SetDefault(c.version, "version")
_ = c.SaveDefault()
_ = c.Reset()
_ = c.read()
if c.Art == nil {
c.Art = map[string]ArtMetadata{}
}

// Refresh if newer version detected
if vers != c.version {
if c.Version != version {
c.Version = version
_ = c.Refresh()
}

Expand All @@ -58,14 +67,13 @@ func (c *ArtCache) download() error {
}
defer res.Body.Close()

// Create new file for zip
// Create zip file
f, e = os.Create(filepath.Join(cacheDir, jsonDir+".zip"))
if e != nil {
return errors.Newf("failed to create zip: %w", e)
}
defer f.Close()

// Save zip to file
if _, e = io.Copy(f, res.Body); e != nil {
return errors.Newf("failed to write zip: %w", e)
}
Expand Down Expand Up @@ -159,22 +167,41 @@ func (c *ArtCache) extractFile(zf *zip.File, dst string) error {

// GetFileOf will return the cached filename for the specified art.
func (c *ArtCache) GetFileOf(name string) string {
return c.GetString("art", name, "file")
if _, ok := c.Art[name]; ok {
return c.Art[name].File
}

return ""
}

// GetHeightOf will return the cached height for the specified art.
func (c *ArtCache) GetHeightOf(name string) int {
return c.GetInt("art", name, "height")
if _, ok := c.Art[name]; ok {
return c.Art[name].Height
}

return 0
}

// GetWidthOf will return the cached width for the specified art.
func (c *ArtCache) GetWidthOf(name string) int {
return c.GetInt("art", name, "width")
if _, ok := c.Art[name]; ok {
return c.Art[name].Width
}

return 0
}

// List will return a list of names for any cached art files.
func (c *ArtCache) List() []string {
return c.GetKeys("art")
var keys []string

for name := range c.Art {
keys = append(keys, name)
}

slices.Sort(keys)
return keys
}

func (c *ArtCache) organize() error {
Expand Down Expand Up @@ -204,22 +231,33 @@ func (c *ArtCache) organize() error {
return nil
}

func (c *ArtCache) read() error {
var b []byte
var e error

if b, e = os.ReadFile(c.file); e != nil {
return errors.Newf("failed to read %s: %w", c.file, e)
}

if e = json.Unmarshal(b, &c); e != nil {
return errors.Newf("invalid cache: %w", e)
}

return nil
}

// Refresh will read any found JSON files and update the art cache.
func (c *ArtCache) Refresh() error {
var addArt filepath.WalkFunc
var arts map[string]any = map[string]any{}
var e error

// Save with initial empty data
_ = c.Set(arts, "art")
_ = c.Set(c.version, "version")
_ = c.Save()
c.Art = map[string]ArtMetadata{}

addArt = func(path string, info os.FileInfo, e error) error {
var a *art.Art

if e != nil {
return errors.Newf("failed to access %s: %w", path, e)
return e
}

if strings.HasSuffix(path, ".json") {
Expand All @@ -228,10 +266,10 @@ func (c *ArtCache) Refresh() error {
return e
}

arts[a.Name] = map[string]any{
"file": path,
"height": a.Height,
"width": a.Width,
c.Art[a.Name] = ArtMetadata{
File: path,
Height: a.Height,
Width: a.Width,
}
}

Expand All @@ -249,13 +287,38 @@ func (c *ArtCache) Refresh() error {
}

// Save with new data, if no errors
_ = c.Set(arts, "art")
_ = c.Set(c.version, "version")
_ = c.Save()

return nil
}

// Save will write the ArtCache to disk.
func (c *ArtCache) Save() error {
var e error

if e = os.MkdirAll(filepath.Dir(c.file), 0o700); e != nil {
return errors.Newf(
"failed to create directory %s: %w",
filepath.Dir(c.file),
e,
)
}

if e = os.WriteFile(c.file, []byte(c.String()), 0o600); e != nil {
return errors.Newf("failed to write %s: %w", c.file, e)
}

return nil
}

// String will return a string representation of the ArtCache.
func (c *ArtCache) String() string {
var b []byte

b, _ = json.MarshalIndent(&c, "", " ")
return strings.TrimSpace(string(b)) + "\n"
}

// Update will download the newest art files from github.com and
// refresh the local cache.
func (c *ArtCache) Update() error {
Expand Down
44 changes: 33 additions & 11 deletions cache/globals.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,40 @@ package cache

import (
"os"
"path/filepath"

"github.com/mjwhitta/errors"
"github.com/mjwhitta/pathname"
)

// Cache related vars
var (
cacheDir string = pathname.ExpandPath("~/.cache/arTTY")
cacheDir string
cacheFile string = "art.json"
jsonDir string = "json"
)

// CustomJSONDir is the location where custom JSON files generated by
// the user are saved.
var CustomJSONDir string = pathname.ExpandPath(
"~/.config/arTTY/" + jsonDir,
)
var CustomJSONDir string

func init() {
var e error
var sys string = "/usr/local/share/arTTY"

if ok, e := pathname.DoesExist(CustomJSONDir); e != nil {
panic(errors.Newf("failed to access cache directory: %w", e))
} else if !ok {
if e := os.MkdirAll(CustomJSONDir, os.ModePerm); e != nil {
e = errors.Newf("failed to create cache directory: %w", e)
panic(e)
}
// Find and create cache directory
if cacheDir, e = os.UserCacheDir(); e != nil {
panic(errors.Newf("user has no cache directory: %w", e))
}

cacheDir = filepath.Join(cacheDir, "arTTY")
if e = os.MkdirAll(cacheDir, 0o700); e != nil {
e = errors.Newf(
"failed to create directory %s: %w",
cacheDir,
e,
)
panic(e)
}

// Check if system cache exists
Expand All @@ -38,4 +44,20 @@ func init() {
cacheDir = sys
}
}

// Find and create custom JSON directory
if CustomJSONDir, e = os.UserConfigDir(); e != nil {
panic(errors.Newf("user has no config directory: %w", e))
}

CustomJSONDir = filepath.Join(CustomJSONDir, "arTTY", jsonDir)
if e = os.MkdirAll(CustomJSONDir, 0o700); e != nil {
e = errors.Newf("failed to create %s: %w", CustomJSONDir, e)
e = errors.Newf(
"failed to create directory %s: %w",
CustomJSONDir,
e,
)
panic(e)
}
}
46 changes: 23 additions & 23 deletions cmd/arTTY/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,61 +264,61 @@ func init() {
func setupConfig() {
// Check all and plain first
if flags.all || flags.plain {
_ = config.Set("", "art")
_ = config.Set("", "exclude")
_ = config.Set(false, "fit")
_ = config.Set("", "match")
cfg.Art = ""
cfg.Exclude = ""
cfg.Fit = false
cfg.Match = ""
}

if flags.plain {
_ = config.Set(false, "bsfact")
_ = config.Set(false, "clear_screen")
_ = config.Set(false, "devexcuse")
_ = config.Set(false, "fortune")
_ = config.Set(false, "random")
_ = config.Set(false, "sysinfo")
cfg.BSFact = false
cfg.ClearScreen = false
cfg.DevExcuse = false
cfg.Fortune = false
cfg.Random = false
cfg.SysInfo = false
}

// Check all other flags
if flags.bsfact {
_ = config.Set(true, "bsfact")
cfg.BSFact = true
}

if flags.clear {
_ = config.Set(true, "clear_screen")
cfg.ClearScreen = true
}

if flags.devexcuse {
_ = config.Set(true, "devexcuse")
cfg.DevExcuse = true
}

if flags.exclude != "" {
_ = config.Set(flags.exclude, "exclude")
cfg.Exclude = flags.exclude
}

if flags.fields != "" {
_ = config.Set(strings.Split(flags.fields, ","), "fields")
_ = config.Set(true, "sysinfo")
cfg.Fields = strings.Split(flags.fields, ",")
cfg.SysInfo = true
}

if flags.fit {
_ = config.Set(true, "fit")
cfg.Fit = true
}

if flags.fortune {
_ = config.Set(true, "fortune")
cfg.Fortune = true
}

if flags.match != "" {
_ = config.Set(flags.match, "match")
cfg.Match = flags.match
}

if flags.random {
_ = config.Set(true, "random")
cfg.Random = true
}

if flags.sysinfo {
_ = config.Set(true, "sysinfo")
cfg.SysInfo = true
}
}

Expand All @@ -337,8 +337,8 @@ func validate() {

// Validate cli flags
if cli.NArg() == 1 {
_ = config.Set(cli.Arg(0), "art")
_ = config.Set(false, "random")
cfg.Art = cli.Arg(0)
cfg.Random = false
} else if cli.NArg() > 1 {
cli.Usage(ExtraArgument)
}
Expand Down
Loading

0 comments on commit 430a64c

Please sign in to comment.