diff --git a/internal/dlcache/dlcache.go b/internal/dlcache/dlcache.go new file mode 100644 index 0000000..c62e471 --- /dev/null +++ b/internal/dlcache/dlcache.go @@ -0,0 +1,61 @@ +package dlcache + +import ( + "encoding/hex" + "io" + "os" + "path/filepath" + + "crypto/sha1" + + "go.arsenm.dev/lure/internal/config" +) + +var BasePath = filepath.Join(config.CacheDir, "dl") + +func New(id string) (string, error) { + h, err := hashID(id) + if err != nil { + return "", err + } + itemPath := filepath.Join(BasePath, h) + + fi, err := os.Stat(itemPath) + if err == nil || (fi != nil && !fi.IsDir()) { + err = os.RemoveAll(itemPath) + if err != nil { + return "", err + } + } + + err = os.MkdirAll(itemPath, 0o755) + if err != nil { + return "", err + } + + return itemPath, nil +} + +func Get(id string) (string, bool) { + h, err := hashID(id) + if err != nil { + return "", false + } + itemPath := filepath.Join(BasePath, h) + + _, err = os.Stat(itemPath) + if err != nil { + return "", false + } + + return itemPath, true +} + +func hashID(id string) (string, error) { + h := sha1.New() + _, err := io.WriteString(h, id) + if err != nil { + return "", err + } + return hex.EncodeToString(h.Sum(nil)), nil +} diff --git a/internal/dlcache/dlcache_test.go b/internal/dlcache/dlcache_test.go new file mode 100644 index 0000000..c5ff087 --- /dev/null +++ b/internal/dlcache/dlcache_test.go @@ -0,0 +1,56 @@ +package dlcache_test + +import ( + "crypto/sha1" + "encoding/hex" + "io" + "os" + "path/filepath" + "testing" + + "go.arsenm.dev/lure/internal/dlcache" +) + +func init() { + dir, err := os.MkdirTemp("/tmp", "lure-dlcache-test.*") + if err != nil { + panic(err) + } + dlcache.BasePath = dir +} + +func TestNew(t *testing.T) { + const id = "https://example.com" + dir, err := dlcache.New(id) + if err != nil { + t.Errorf("Expected no error, got %s", err) + } + + exp := filepath.Join(dlcache.BasePath, sha1sum(id)) + if dir != exp { + t.Errorf("Expected %s, got %s", exp, dir) + } + + fi, err := os.Stat(dir) + if err != nil { + t.Errorf("stat: expected no error, got %s", err) + } + + if !fi.IsDir() { + t.Errorf("Expected cache item to be a directory") + } + + dir2, ok := dlcache.Get(id) + if !ok { + t.Errorf("Expected Get() to return valid value") + } + if dir2 != dir { + t.Errorf("Expected %s from Get(), got %s", dir, dir2) + } +} + +func sha1sum(id string) string { + h := sha1.New() + _, _ = io.WriteString(h, id) + return hex.EncodeToString(h.Sum(nil)) +}