summaryrefslogtreecommitdiff
path: root/internal/entry
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-10-31 22:50:00 +0200
committerPaul Buetow <paul@buetow.org>2024-10-31 22:50:00 +0200
commitedfbee2da241372271d2a32cff8ab7409e910727 (patch)
tree2d3abe6ce6187661cb90f0620751f4821b1552c0 /internal/entry
parent84e72c59d507cbd7347465c38044e9199ee7903a (diff)
restructure
Diffstat (limited to 'internal/entry')
-rw-r--r--internal/entry/entry.go20
-rw-r--r--internal/entry/sharetags.go45
-rw-r--r--internal/entry/sharetags_test.go102
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
+}