From a6c63b33cac1431f93f76f27e6eb1ae9ee06d8c2 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Fri, 6 Sep 2024 23:21:07 +0300 Subject: add Next --- internal/server/repository/repository.go | 29 ++++++++++++++++++--------- internal/server/repository/repository_test.go | 24 ++++++++++++++++++++++ internal/types/entry.go | 9 ++++----- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/internal/server/repository/repository.go b/internal/server/repository/repository.go index 20482fe..8d2279a 100644 --- a/internal/server/repository/repository.go +++ b/internal/server/repository/repository.go @@ -34,7 +34,7 @@ type entryPair struct { type Repository struct { conf server.ServerConfig - entries map[string]types.Entry + entries map[types.EntryID]types.Entry mu *sync.Mutex fs fs loaded *bool @@ -53,7 +53,7 @@ func newRepository(conf server.ServerConfig, fs fs) Repository { var loaded bool return Repository{ conf: conf, - entries: make(map[string]types.Entry), + entries: make(map[types.EntryID]types.Entry), mu: &sync.Mutex{}, fs: fs, loaded: &loaded, @@ -61,6 +61,20 @@ func newRepository(conf server.ServerConfig, fs fs) Repository { } } +// Gets next entry to be shared for the given social platform. +func (r Repository) Next(platform types.PlatformName) (types.Entry, bool) { + r.mu.Lock() + defer r.mu.Unlock() + + for _, ent := range r.entries { + if !ent.IsShared(platform) { + return ent, true + } + } + + return types.Entry{}, false // No entry found +} + // Load repository into memory if not done yet. func (r Repository) load() error { if *r.loaded { @@ -139,7 +153,7 @@ func (r Repository) put(ent types.Entry) error { return r.fs.WriteFile(r.entryPath(ent), bytes) } -func (r Repository) Get(id string) (types.Entry, error) { +func (r Repository) Get(id types.EntryID) (types.Entry, error) { if !r.getIdRe.MatchString(id) { return types.Entry{}, fmt.Errorf("invalid id %s", id) } @@ -157,7 +171,7 @@ func (r Repository) Get(id string) (types.Entry, error) { return ent, nil } -func (r Repository) GetJSON(id string) (string, error) { +func (r Repository) GetJSON(id types.EntryID) (string, error) { ent, err := r.Get(id) if err != nil { return "", err @@ -252,7 +266,7 @@ func (r Repository) mergeRemotelyFromPartner(ctx context.Context, partner string return easyhttp.GetData(ctx, uri, r.conf.APIKey, pairs) } - getEntry := func(ctx context.Context, partner, id string, ent *types.Entry) error { + getEntry := func(ctx context.Context, partner, id types.EntryID, ent *types.Entry) error { uri := fmt.Sprintf("%s/get?id=%s", partner, id) return easyhttp.GetData(ctx, uri, r.conf.APIKey, ent) } @@ -300,8 +314,3 @@ func (r Repository) mergeFromPartner(ctx context.Context, partner string, return errors.Join(errs...) } - -// Gets next entry to be shared for the given social platform. -func (r Repository) Next(name string) (types.Entry, bool) { - return types.Entry{}, false -} diff --git a/internal/server/repository/repository_test.go b/internal/server/repository/repository_test.go index 07b755a..c35d7f2 100644 --- a/internal/server/repository/repository_test.go +++ b/internal/server/repository/repository_test.go @@ -294,6 +294,30 @@ func TestRepositoryMergeFromPartner(t *testing.T) { }) } +func TestRepositoryNext(t *testing.T) { + t.Parallel() + + fs := make(vfs.MemoryFS) + repo := newRepository(server.ServerConfig{DataDir: "./data"}, fs) + entries := makeEntries(t) + + for _, ent := range entries { + _ = repo.put(ent) + } + + if ent, ok := repo.Next("Mastodon"); ok { + t.Error("expected no Mastodon entry to be found", ent) + } + + if _, ok := repo.Next("LinkedIn"); !ok { + t.Error("expected an unshared LinkedIn entry to be found") + } + + if _, ok := repo.Next("DoesNotYetExist"); !ok { + t.Error("expected an unshared DoesNotYetExist entry to be found") + } +} + func makeEntries(t *testing.T) []types.Entry { ent1, err := makeAnEntry() if err != nil { diff --git a/internal/types/entry.go b/internal/types/entry.go index 0fbbcce..2f044f3 100644 --- a/internal/types/entry.go +++ b/internal/types/entry.go @@ -10,9 +10,12 @@ import ( "strings" ) +type PlatformName = string +type EntryID = string + type Entry struct { // The unique ID of this entry. - ID string `json:"id,omitempty"` + ID EntryID `json:"id,omitempty"` Body string `json:"body"` Shared map[PlatformName]Shared `json:"shared,omitempty"` Epoch int `json:"epoch,omitempty"` @@ -158,11 +161,7 @@ func (e Entry) checksumBase() string { for platform := range e.Shared { platforms = append(platforms, platform) } - sort.Strings(platforms) - // slices.SortFunc(platforms, func(a, b SocialPlatform) int { - // return cmp.Compare(a.Name(), b.Name()) - // }) for i, patform := range platforms { if i > 0 { -- cgit v1.2.3