Skip to content

Commit

Permalink
Set deck timestamps to their DateAdded time
Browse files Browse the repository at this point in the history
Issue: #26
  • Loading branch information
strib committed Feb 5, 2023
1 parent 4188a45 commit 0befa77
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 62 deletions.
50 changes: 32 additions & 18 deletions fusefs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"syscall"
"time"

"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
Expand Down Expand Up @@ -308,16 +309,25 @@ func (dcd *FSDeckCardsDir) Readdir(ctx context.Context) (
// FSDeck represents the directory containing info about one deck.
type FSDeck struct {
fs.Inode
s forgefs.Storage
da forgefs.DataFetcher
im *fsutil.ImageManager
id string
s forgefs.Storage
da forgefs.DataFetcher
im *fsutil.ImageManager
id string
dateAdded time.Time
}

var _ fs.InodeEmbedder = (*FSDeck)(nil)
var _ fs.NodeGetattrer = (*FSDeck)(nil)
var _ fs.NodeLookuper = (*FSDeck)(nil)
var _ fs.NodeReaddirer = (*FSDeck)(nil)

// Getattr implements the fs.NodeGetattrer interface.
func (d *FSDeck) Getattr(
ctx context.Context, _ fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
out.SetTimes(&d.dateAdded, &d.dateAdded, &d.dateAdded)
return 0
}

func (d *FSDeck) getDeck(ctx context.Context) (*forgefs.Deck, error) {
deck, err := d.s.GetDeck(ctx, d.id)
if err != nil {
Expand Down Expand Up @@ -424,7 +434,7 @@ type FSMyDecksDir struct {
da forgefs.DataFetcher
im *fsutil.ImageManager

decks map[string]string
decks map[string]forgefs.DeckMetadata
filterRoot *filter.Node
}

Expand All @@ -436,14 +446,14 @@ func NewFSMyDecksDir(
s: s,
da: da,
im: im,
decks: make(map[string]string),
decks: make(map[string]forgefs.DeckMetadata),
}
names, err := mdd.s.GetMyDeckNames(ctx)
mds, err := mdd.s.GetMyDeckMetadata(ctx)
if err != nil {
return nil, fs.ToErrno(err)
}
for id, name := range names {
mdd.decks[name] = id
for _, md := range mds {
mdd.decks[md.Name] = md
}
return mdd, nil
}
Expand All @@ -458,15 +468,15 @@ func NewFSMyDecksDirWithFilter(
s: s,
da: da,
im: im,
decks: make(map[string]string),
decks: make(map[string]forgefs.DeckMetadata),
filterRoot: filterRoot,
}
names, err := mdd.s.GetMyDeckNamesWithFilter(ctx, filterRoot)
mds, err := mdd.s.GetMyDeckMetadataWithFilter(ctx, filterRoot)
if err != nil {
return nil, fs.ToErrno(err)
}
for id, name := range names {
mdd.decks[name] = id
for _, md := range mds {
mdd.decks[md.Name] = md
}
return mdd, nil
}
Expand All @@ -484,7 +494,7 @@ func (mdd *FSMyDecksDir) Lookup(
return n, 0
}

id, ok := mdd.decks[name]
md, ok := mdd.decks[name]
if !ok {
// See if it's a filter.
filterRoot, err := filter.Parse(name)
Expand All @@ -511,13 +521,17 @@ func (mdd *FSMyDecksDir) Lookup(
})
} else {
n = mdd.NewInode(ctx, &FSDeck{
s: mdd.s,
da: mdd.da,
id: id,
im: mdd.im,
s: mdd.s,
da: mdd.da,
id: md.ID,
im: mdd.im,
dateAdded: md.DateAdded,
}, fs.StableAttr{
Mode: syscall.S_IFDIR,
})

// Set the times.
out.SetTimes(&md.DateAdded, &md.DateAdded, &md.DateAdded)
}

ok = mdd.AddChild(name, n, false)
Expand Down
72 changes: 56 additions & 16 deletions fusefs/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"path/filepath"
"strconv"
"testing"
"time"

"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
Expand Down Expand Up @@ -123,15 +124,23 @@ func (ms *mockStorage) StoreDecks(
return nil
}

func (ms *mockStorage) GetMyDeckNames(_ context.Context) (
names map[string]string, err error) {
names = make(map[string]string, len(ms.decks))
func (ms *mockStorage) GetMyDeckMetadata(_ context.Context) (
mds map[string]forgefs.DeckMetadata, err error) {
mds = make(map[string]forgefs.DeckMetadata, len(ms.decks))
for id, d := range ms.decks {
if d.OwnedByMe {
names[id] = d.DeckInfo.Name
dateAdded, err := time.Parse("2006-01-02", d.DeckInfo.DateAdded)
if err != nil {
return nil, err
}
mds[id] = forgefs.DeckMetadata{
ID: id,
Name: d.DeckInfo.Name,
DateAdded: dateAdded,
}
}
}
return names, nil
return mds, nil
}

func mockFilter(n *filter.Node, d forgefs.Deck) (bool, error) {
Expand Down Expand Up @@ -194,10 +203,10 @@ func mockFilter(n *filter.Node, d forgefs.Deck) (bool, error) {
}
}

func (ms *mockStorage) GetMyDeckNamesWithFilter(
func (ms *mockStorage) GetMyDeckMetadataWithFilter(
_ context.Context, filterRoot *filter.Node) (
names map[string]string, err error) {
names = make(map[string]string)
mds map[string]forgefs.DeckMetadata, err error) {
mds = make(map[string]forgefs.DeckMetadata)
for id, d := range ms.decks {
if !d.OwnedByMe {
continue
Expand All @@ -208,10 +217,18 @@ func (ms *mockStorage) GetMyDeckNamesWithFilter(
return nil, err
}
if match {
names[id] = d.DeckInfo.Name
dateAdded, err := time.Parse("2006-01-02", d.DeckInfo.DateAdded)
if err != nil {
return nil, err
}
mds[id] = forgefs.DeckMetadata{
ID: id,
Name: d.DeckInfo.Name,
DateAdded: dateAdded,
}
}
}
return names, nil
return mds, nil
}

func (ms *mockStorage) GetSampleDeckWithVersion(ctx context.Context) (
Expand Down Expand Up @@ -315,13 +332,16 @@ func makeCard(id, title, url string) forgefs.Card {
}
}

func makeDeck(id, name string, mine bool, a, e float64) forgefs.Deck {
func makeDeck(
id, name string, mine bool, a, e float64,
dateAdded time.Time) forgefs.Deck {
return forgefs.Deck{
DeckInfo: forgefs.DeckInfo{
AmberControl: a,
ExpectedAmber: e,
KeyforgeID: id,
Name: name,
DateAdded: dateAdded.Format("2006-01-02"),
},
OwnedByMe: mine,
}
Expand All @@ -346,11 +366,15 @@ func TestFSSimple(t *testing.T) {
d1ID := "3"
d1Name := "deck1"
d1Image := []byte{3, 4, 1, 2}
d1 := makeDeck(d1ID, d1Name, true, 10, 20)
d1DateAdded, err := time.Parse("2006-01-02", "2023-01-01")
require.NoError(t, err)
d1 := makeDeck(d1ID, d1Name, true, 10, 20, d1DateAdded)
d2ID := "4"
d2Name := "deck2"
d2Image := []byte{4, 1, 2, 3}
d2 := makeDeck(d2ID, d2Name, true, 3, 30)
d2DateAdded, err := time.Parse("2006-01-02", "2023-01-02")
require.NoError(t, err)
d2 := makeDeck(d2ID, d2Name, true, 3, 30, d2DateAdded)

decks := []forgefs.Deck{d1, d2}
mdf.myDecks = map[string]forgefs.Deck{
Expand All @@ -367,7 +391,7 @@ func TestFSSimple(t *testing.T) {
d2ID: d2Image,
}

err := ms.StoreCards(ctx, mdf.cards)
err = ms.StoreCards(ctx, mdf.cards)
require.NoError(t, err)
err = ms.StoreDecks(ctx, decks)
require.NoError(t, err)
Expand Down Expand Up @@ -399,16 +423,27 @@ func TestFSSimple(t *testing.T) {
mountTmpDir(t, mountpoint, root)

// Check the root dir.
checkDir := func(dir string, expectedNames []string) {
checkDirWithTimestamps := func(
dir string, expectedNames []string,
expectedTimestamps map[string]time.Time) {
entries, err := os.ReadDir(dir)
require.NoError(t, err)
require.Len(t, entries, len(expectedNames))
names := make([]string, len(expectedNames))
for i, e := range entries {
names[i] = e.Name()
et, ok := expectedTimestamps[e.Name()]
if ok {
info, err := e.Info()
require.NoError(t, err)
require.Equal(t, et.UTC(), info.ModTime().UTC())
}
}
require.ElementsMatch(t, expectedNames, names)
}
checkDir := func(dir string, expectedNames []string) {
checkDirWithTimestamps(dir, expectedNames, nil)
}
checkDir(mountpoint, []string{fsutil.CardsDir, fsutil.MyDecksDir})

// Check cards.
Expand Down Expand Up @@ -443,7 +478,12 @@ func TestFSSimple(t *testing.T) {

// Check my-decks dir.
decksDir := filepath.Join(mountpoint, fsutil.MyDecksDir)
checkDir(decksDir, []string{d1Name, d2Name})
checkDirWithTimestamps(
decksDir, []string{d1Name, d2Name},
map[string]time.Time{
d1Name: d1DateAdded,
d2Name: d2DateAdded,
})

// Check deck dir.
d1Dir := filepath.Join(decksDir, d1Name)
Expand Down
15 changes: 8 additions & 7 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ type Storage interface {
// StoreDecks stores all the given decks, overwriting any existing
// decks with the same IDs as the new decks.
StoreDecks(ctx context.Context, decks []Deck) error
// GetMyDeckNames gets all the decks owned by the user running the
// program. It returns a map of deckID -> deckName.
GetMyDeckNames(ctx context.Context) (names map[string]string, err error)
// GetMyDeckNamesWithFilter gets all the decks owned by the user,
// GetMetadataNames gets all the decks owned by the user running the
// program. It returns a map of deckID -> metadata.
GetMyDeckMetadata(ctx context.Context) (
mds map[string]DeckMetadata, err error)
// GetMyDeckMetadataWithFilter gets all the decks owned by the user,
// which also match the given filter. It returns a map of deckID
// -> deckName.
GetMyDeckNamesWithFilter(ctx context.Context, filterRoot *filter.Node) (
names map[string]string, err error)
// -> metadata.
GetMyDeckMetadataWithFilter(ctx context.Context, filterRoot *filter.Node) (
mds map[string]DeckMetadata, err error)
// GetDeck returns the full deck object for the given `id`.
GetDeck(ctx context.Context, id string) (deck *Deck, err error)
// GetSampleDeckWithVersion returns a sample deck and its SAS version.
Expand Down
Loading

0 comments on commit 0befa77

Please sign in to comment.