ref: 306492836ca1640352b80505b7d43f1ee16ea263
parent: 5b4518b98650dcd4db66a3182c4c265efa3b7dc3
author: penny <penny@limitedideas.org>
date: Mon Aug 18 13:39:21 EDT 2025
Add status filtering
--- a/commands.go
+++ b/commands.go
@@ -6,7 +6,7 @@
"github.com/google/shlex"
)
-var commands = []string{"examine", "reply", "like", "thread", "open", "preview", "download", "dm", "rt", "parent", "children", "rm", "mark", "unmark", "account", "vim", "import", "pause", "resume", "url"}+var commands = []string{"examine", "reply", "like", "thread", "open", "preview", "download", "dm", "rt", "parent", "children", "rm", "mark", "unmark", "account", "vim", "import", "pause", "resume", "url", "fpost"} func processInput(input string) (command string, arguments string) {--- /dev/null
+++ b/filtering.go
@@ -1,0 +1,67 @@
+package main
+
+import (
+ "context"
+ "strconv"
+
+ "github.com/mattn/go-mastodon"
+)
+
+func (hc *Hellclient) getFilterID(title string) (ID int) {+ filters, _ := hc.client.GetFiltersV2(context.Background())
+ for _, filter := range filters {+ if filter.Title == title {+ ID, _ = strconv.Atoi(string(filter.ID))
+ return ID
+ }
+ }
+ return
+}
+
+func (hc *Hellclient) createNewFilter(title string,
+ filtercontext []string, action string) (result *mastodon.FilterV2, err error) {+ filter := &mastodon.FilterV2{+ Title: title,
+ Context: filtercontext,
+ Action: action,
+ }
+ result, err = hc.client.CreateFilterV2(context.Background(), filter)
+ if err != nil {+ return nil, err
+ }
+ return
+}
+
+func (hc *Hellclient) GetOrCreateFilter(title string,
+ filtercontext []string, action string) (result *mastodon.FilterV2, err error) {+ ID := hc.getFilterID(title)
+
+ if ID == 0 {+ result, err = hc.createNewFilter(title, filtercontext, action)
+ if err == nil {+ ID, _ = strconv.Atoi(string(result.ID))
+ }
+ } else {+ MID := mastodon.ID(strconv.Itoa(ID))
+ result = &mastodon.FilterV2{+ ID: MID,
+ }
+ }
+ if err != nil {+ return
+ }
+
+ return
+}
+
+func (hc *Hellclient) filterStatus(status *mastodon.Status) (result *mastodon.FilterV2, err error) {+ result, err = hc.GetOrCreateFilter("hellclient status filter", []string{"notifications", "public", "thread", "account"}, "hide")+
+ if err != nil {+ return
+ }
+
+ result, err = hc.client.FilterAddStatus(context.Background(), status.ID, result)
+
+ return
+}
--- a/format.go
+++ b/format.go
@@ -18,7 +18,7 @@
if width < 2 {return input
}
-
+
longline := false
if len(remainder) > width {longline = true
@@ -68,14 +68,14 @@
remainder = remainder[width-1:]
}
}
-
+
result = append(result, remainder...)
//Sometimes posts come from mastodon with a newline/space at the end
//you can actually see it in the web interface
- if(strings.HasSuffix(string(result), " ")) {+ if strings.HasSuffix(string(result), " ") {result = result[:len(result)-1]
}
- if(strings.HasSuffix(string(result), "\n")) {+ if strings.HasSuffix(string(result), "\n") {result = result[:len(result)-1]
}
//Put a newline at the end if status takes multiple lines
--- a/go.mod
+++ b/go.mod
@@ -3,11 +3,12 @@
go 1.24.5
require (
- github.com/chzyer/readline v1.5.1
+ github.com/ergochat/readline v0.1.3
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/k3a/html2text v1.2.1
github.com/mattn/go-mastodon v0.0.10
golang.org/x/net v0.42.0
+ golang.org/x/term v0.33.0
)
require (
@@ -14,4 +15,7 @@
github.com/gorilla/websocket v1.5.3 // indirect
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
golang.org/x/sys v0.34.0 // indirect
+ golang.org/x/text v0.27.0 // indirect
)
+
+replace github.com/mattn/go-mastodon => /Users/penny/go/pkg/go-mastodon
--- a/go.sum
+++ b/go.sum
@@ -1,9 +1,5 @@
-github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
-github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
-github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
-github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
-github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
-github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
+github.com/ergochat/readline v0.1.3 h1:/DytGTmwdUJcLAe3k3VJgowh5vNnsdifYT6uVaf4pSo=
+github.com/ergochat/readline v0.1.3/go.mod h1:o3ux9QLHLm77bq7hDB21UTm6HlV2++IPDMfIfKDuOgY=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@@ -14,8 +10,6 @@
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/k3a/html2text v1.2.1 h1:nvnKgBvBR/myqrwfLuiqecUtaK1lB9hGziIJKatNFVY=
github.com/k3a/html2text v1.2.1/go.mod h1:ieEXykM67iT8lTvEWBh6fhpH4B23kB9OMKPdIBmgUqA=
-github.com/mattn/go-mastodon v0.0.10 h1:wz1d/aCkJOIkz46iv4eAqXHVreUMxydY1xBWrPBdDeE=
-github.com/mattn/go-mastodon v0.0.10/go.mod h1:YBofeqh7G6s787787NQR8erBYz6fKDu+KNMrn5RuD6Y=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
@@ -27,8 +21,11 @@
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
+golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
+golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
--- a/hellclient.go
+++ b/hellclient.go
@@ -1,6 +1,7 @@
package main
import (
+ "context"
"io"
"strings"
"sync"
@@ -16,11 +17,11 @@
type Hellclient struct {//if you're gonna touch or read anything here lock the mutex with hc.lock()
- isPaused bool
- rl *readline.Instance
- client *mastodon.Client
- account *mastodon.Account
- block sync.Mutex
+ isPaused bool
+ rl *readline.Instance
+ client *mastodon.Client
+ currentuser *mastodon.Account
+ block sync.Mutex
homeMap map[string]*mastodon.Status
urlMap map[string][]string
@@ -39,13 +40,22 @@
return nil, err
}
client := initClient(account)
- homeMap := make(map[string]*mastodon.Status)
- debugMap := make(map[string]interface{})- urlMap := make(map[string][]string)
+ currentuser, err := client.GetAccountCurrentUser(context.Background())
if err != nil {return nil, err
}
- return &Hellclient{rl: rl, homeMap: homeMap, debugMap: debugMap, isPaused: false, urlMap: urlMap, client: client}, nil+
+ homeMap := make(map[string]*mastodon.Status)
+ debugMap := make(map[string]interface{})+ urlMap := make(map[string][]string)
+ return &Hellclient{rl: rl,+ homeMap: homeMap,
+ debugMap: debugMap,
+ isPaused: false,
+ urlMap: urlMap,
+ client: client,
+ currentuser: currentuser,
+ }, nil
}
func (hc *Hellclient) updatePrompt() {--- a/main.go
+++ b/main.go
@@ -21,7 +21,6 @@
rl := hc.rl
client := hc.client
-
//Horrible io pipe hack
//Replaces system stdout with the readline one
r, w, _ := os.Pipe()
@@ -38,10 +37,7 @@
interupted := false //use this to check if we were interupted last turn
var recentpost *mastodon.Status
- currentUser, err := client.GetAccountCurrentUser(context.Background())
-
if err != nil {- fmt.Println("Couldn't get our own profile: %v\n", err)return
}
@@ -54,7 +50,7 @@
//If the next line is empty, exit the program
//If it isn't empty, we were just clearing the line
if interupted {- if(len(line) == 0) {+ if len(line) == 0 {os.Exit(0)
} else {interupted = false
@@ -94,11 +90,11 @@
defer hc.unlock()
index, content, _ := strings.Cut(arguments, " ")
-
+
postItem, postOK := homeMap[index]
debugItem, debugOK := debugMap[index]
-
- if (postOK) {+
+ if postOK {lastindex = index
} else {postItem, postOK = homeMap[lastindex]
@@ -292,17 +288,23 @@
account := postItem.Account
fmt.Printf(formatAccount(&account))
return
+ case "fpost":
+ _, err := hc.filterStatus(postItem)
+ if err != nil {+ fmt.Printf("Error filtering post: %v\n", err)+ }
+ return
}
-
+
//Posts that need an index and an argument
if content == "" { fmt.Printf("\"%v\" requires an argument\n", command)return
}
-
+
switch command {case "reply":
- recentpost, err = postReply(content, *client, postItem.ID, currentUser.ID, postItem)
+ recentpost, err = postReply(content, *client, postItem.ID, hc.currentuser.ID, postItem)
if err != nil {fmt.Println(err)
}
--- a/mastodon.go
+++ b/mastodon.go
@@ -125,29 +125,29 @@
return rendered.String()
}
-func processStatusHints (toot *mastodon.Toot, postpointer *string) {+func processStatusHints(toot *mastodon.Toot, postpointer *string) {posttext := *postpointer
posttext, hints := extractInputParameters(posttext)
toot.Status = posttext
-
+
for _, arg := range hints {key := arg[0]
val := arg[1]
switch key {- case "unlisted":
- toot.Visibility = "unlisted"
- case "public":
- toot.Visibility = "public"
- case "followers":
- toot.Visibility = "private"
- case "direct":
- toot.Visibility = "direct"
- case "subject":
- if(len(val) > 0) {- toot.SpoilerText = val
- }
- case "sensitive":
- toot.Sensitive = true
+ case "unlisted":
+ toot.Visibility = "unlisted"
+ case "public":
+ toot.Visibility = "public"
+ case "followers":
+ toot.Visibility = "private"
+ case "direct":
+ toot.Visibility = "direct"
+ case "subject":
+ if len(val) > 0 {+ toot.SpoilerText = val
+ }
+ case "sensitive":
+ toot.Sensitive = true
}
}
*postpointer = posttext
@@ -158,11 +158,11 @@
Status: posttext,
InReplyToID: replyto,
}
-
+
toot.Visibility = postItem.Visibility
-
+
processStatusHints(&toot, &posttext)
-
+
if currentuser == postItem.Account.ID {status, err = postStatusDetailed(client, toot)
return
@@ -172,7 +172,7 @@
sb.WriteString(getUserString(postItem))
sb.WriteString(" ")sb.WriteString(posttext)
-
+
toot.Status = sb.String()
status, err = postStatusDetailed(client, toot)
return
@@ -184,7 +184,7 @@
Status: posttext,
Visibility: visibility,
}
-
+
processStatusHints(&toot, &posttext)
status, err = postStatusDetailed(client, toot)
@@ -192,7 +192,7 @@
}
func postStatusDetailed(client mastodon.Client, toot mastodon.Toot) (status *mastodon.Status, err error) {-
+
status, err = client.PostStatus(context.Background(), &toot)
return
}
--
⑨