diff options
| author | Paul Buetow <paul@buetow.org> | 2024-10-31 22:50:00 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-10-31 22:50:00 +0200 |
| commit | edfbee2da241372271d2a32cff8ab7409e910727 (patch) | |
| tree | 2d3abe6ce6187661cb90f0620751f4821b1552c0 /internal/entry | |
| parent | 84e72c59d507cbd7347465c38044e9199ee7903a (diff) | |
restructure
Diffstat (limited to 'internal/entry')
| -rw-r--r-- | internal/entry/entry.go | 20 | ||||
| -rw-r--r-- | internal/entry/sharetags.go | 45 | ||||
| -rw-r--r-- | internal/entry/sharetags_test.go | 102 |
3 files changed, 166 insertions, 1 deletions
diff --git a/internal/entry/entry.go b/internal/entry/entry.go index be3bb80..d757632 100644 --- a/internal/entry/entry.go +++ b/internal/entry/entry.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "codeberg.org/snonux/gos/internal/config" "codeberg.org/snonux/gos/internal/oi" "codeberg.org/snonux/gos/internal/prompt" "codeberg.org/snonux/gos/internal/timestamp" @@ -18,7 +19,7 @@ type State int const ( Unknown State = iota - Inboxed // TODO: Implement + Inboxed Queued Posted ) @@ -152,6 +153,15 @@ func (e Entry) HasTag(tag string) bool { return slices.Contains(e.simpleTags, tag) } +// Valid tags are: share:foo[,...] +// whereas foo can be a supported plutform such as linkedin, mastodon, etc. +// foo can also be prefixed with - to exclude it. See unit tests for examples. +func (e Entry) ExcludedByTags(args config.Args, platform string) (bool, error) { + s, err := newShareTags(args, e.Path) + return slices.Contains(s.excludes, strings.ToLower(platform)) || + !slices.Contains(s.includes, strings.ToLower(platform)), err +} + func (e Entry) Edit() error { if err := prompt.EditFile(e.Path); err != nil { return err @@ -163,6 +173,14 @@ func (e Entry) Remove() error { return os.Remove(e.Path) } +func (e Entry) FileAction(question string) error { + content, _, err := e.Content() + if err != nil { + return err + } + return prompt.FileAction(question, content, e.Path) +} + func extractURLs(input string) []string { urlPattern := `(http://|https://|ftp://)[^\s]+` re := regexp.MustCompile(urlPattern) diff --git a/internal/entry/sharetags.go b/internal/entry/sharetags.go new file mode 100644 index 0000000..4a7f0cf --- /dev/null +++ b/internal/entry/sharetags.go @@ -0,0 +1,45 @@ +package entry + +import ( + "fmt" + "slices" + "strings" + + "codeberg.org/snonux/gos/internal/config" +) + +type shareTags struct { + includes []string // The platforms to include + excludes []string // The platforms to exclude +} + +func newShareTags(args config.Args, filePath string) (shareTags, error) { + var s shareTags + + parts := strings.Split(filePath, ".") + if len(parts) < 4 { + return s, fmt.Errorf("invalid file path: %s", filePath) + } + tagStr := parts[len(parts)-4] + + if len(parts) > 2 && strings.HasPrefix(tagStr, "share:") { + for _, tag := range strings.Split(tagStr[6:], ":") { + if strings.HasPrefix(tag, "-") { + s.excludes = append(s.excludes, strings.ToLower(tag[1:])) + } else { + s.includes = append(s.includes, strings.ToLower(tag)) + } + } + } + + if len(s.includes) == 0 { + for platform := range args.Platforms { + if slices.Contains(s.excludes, strings.ToLower(platform)) { + continue + } + s.includes = append(s.includes, strings.ToLower(platform)) + } + } + + return s, nil +} diff --git a/internal/entry/sharetags_test.go b/internal/entry/sharetags_test.go new file mode 100644 index 0000000..ba97842 --- /dev/null +++ b/internal/entry/sharetags_test.go @@ -0,0 +1,102 @@ +package entry + +import ( + "slices" + "testing" + + "codeberg.org/snonux/gos/internal/config" +) + +func TestShareTagsPositive(t *testing.T) { + args := config.Args{Platforms: map[string]int{"mastodon": 100, "linkedin": 100}} + testTable := map[string]shareTags{ + "./foo/bar.without.tags.txt.20240101-010101.queued": { + includes: []string{"mastodon", "linkedin"}, + }, + "./foo/bar.share:linkeDin.txt.20240101-010101.queued": { + includes: []string{"linkedin"}, + }, + "./foo/bar.share:-LinkedIn.txt.20240101-010101.queued": { + includes: []string{"mastodon"}, + excludes: []string{"linkedin"}, + }, + "./foo/bar.share:linkedin:mastOdon.txt.20240101-010101.queued": { + includes: []string{"linkedin", "mastodon"}, + }, + "./foo/bar.share:linkediN:-mastodon:XCOM.txt.20240101-010101.queued": { + includes: []string{"linkedin", "xcom"}, + excludes: []string{"mastodon"}, + }, + "./foo/bar/ql-e7657e8a1ab573f84ad0dbc55199e937.share:-mastodon.txt.20241018-105524.queued": { + includes: []string{"linkedin"}, + excludes: []string{"mastodon"}, + }, + } + + for filePath, expectedResult := range testTable { + t.Run(filePath, func(t *testing.T) { + shareTags, err := newShareTags(args, filePath) + if err != nil { + t.Error(err) + } + if !sameElements(shareTags.includes, expectedResult.includes) { + t.Errorf("Expected includes to be %v but got %v with %s", + expectedResult.includes, shareTags.includes, filePath) + } + if !sameElements(shareTags.excludes, expectedResult.excludes) { + t.Errorf("Expected excludes to be %v but got %v with %s", + expectedResult.excludes, shareTags.excludes, filePath) + } + }) + + } +} +func TestShareTagsNegative(t *testing.T) { + args := config.Args{Platforms: map[string]int{"mastodon": 100, "linkedin": 100}} + testTable := map[string]shareTags{ + "./foo/bar.without.tags.txt.20240101-010101.queued": { + includes: []string{"linkedin"}, + }, + "./foo/bar.share:linkedIn.txt.20240101-010101.queued": { + includes: []string{"mastodon"}, + }, + "./foo/bar.share:-liNkedin.txt.20240101-010101.queued": { + includes: []string{"linkedin"}, + }, + "./foo/bar.share:linkedin:mastodon.txt.20240101-010101.queued": { + includes: []string{"oups", "mastodon"}, + }, + "./foo/bar.share:linkedin:-MASTODON:xcom.txt.20240101-010101.queued": { + includes: []string{"linkedin", "xcom"}, + excludes: []string{"mastodon", "xcom"}, + }, + } + + for filePath, unexpectedResult := range testTable { + t.Run(filePath, func(t *testing.T) { + shareTags, err := newShareTags(args, filePath) + if err != nil { + t.Error(err) + } + if sameElements(shareTags.includes, unexpectedResult.includes) && + sameElements(shareTags.excludes, unexpectedResult.excludes) { + t.Errorf("expected %v not to be the actual result with %s", + unexpectedResult, filePath) + } + }) + + } +} + +// Can't use slices.Equal as order of elements may be different. +func sameElements(a, b []string) bool { + if len(a) != len(b) { + return false + } + for _, elem := range a { + if !slices.Contains(b, elem) { + return false + } + } + return true +} |
