Adds GetFollowedTags

pull/179/head
Paul Waldo 2023-03-12 09:25:45 -04:00
parent 9faaa4f0dc
commit 589be3c1f8
No known key found for this signature in database
GPG Key ID: 7CD5C6BB0D0BB7F4
7 changed files with 168 additions and 5 deletions

25
.vscode/launch.json vendored 100644
View File

@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"console": "integratedTerminal"
},
{
"name": "mstdn",
"type": "go",
"request": "launch",
"mode": "auto",
// "cwd": "${workspaceFolder}/cmd/mstdn",
"program": "${workspaceFolder}/cmd/mstdn",
"console": "integratedTerminal"
}
]
}

View File

@ -2,6 +2,7 @@ package mastodon
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
@ -32,6 +33,7 @@ type Account struct {
Bot bool `json:"bot"` Bot bool `json:"bot"`
Discoverable bool `json:"discoverable"` Discoverable bool `json:"discoverable"`
Source *AccountSource `json:"source"` Source *AccountSource `json:"source"`
FollowedTag []FollowedTag `json:"followed_tags"`
} }
// Field is a Mastodon account profile field. // Field is a Mastodon account profile field.
@ -50,6 +52,40 @@ type AccountSource struct {
Fields *[]Field `json:"fields"` Fields *[]Field `json:"fields"`
} }
// UnixTimeString represents a time in a Unix Epoch string
type UnixTimeString struct {
time.Time
}
func (u *UnixTimeString) UnmarshalJSON(b []byte) error {
var timestampSring string
err := json.Unmarshal(b, &timestampSring)
if err != nil {
return err
}
timestamp, err := strconv.ParseInt(timestampSring, 0, 0)
if err != nil {
return err
}
u.Time = time.Unix(timestamp, 0)
return nil
}
// History is the history of a followed tag
type FollowedTagHistory struct {
Day UnixTimeString `json:"day,omitempty"`
Accounts int `json:"accounts,string,omitempty"`
Uses int `json:"uses,string,omitempty"`
}
// FollowedTag is a Hash Tag followed by the user
type FollowedTag struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
History []FollowedTagHistory `json:"history,omitempty"`
Following bool `json:"following,omitempty"`
}
// GetAccount return Account. // GetAccount return Account.
func (c *Client) GetAccount(ctx context.Context, id ID) (*Account, error) { func (c *Client) GetAccount(ctx context.Context, id ID) (*Account, error) {
var account Account var account Account
@ -326,3 +362,13 @@ func (c *Client) GetMutes(ctx context.Context, pg *Pagination) ([]*Account, erro
} }
return accounts, nil return accounts, nil
} }
// GetMutes returns the list of users muted by the current user.
func (c *Client) GetFollowedTags(ctx context.Context, pg *Pagination) ([]*FollowedTag, error) {
var followedTags []*FollowedTag
err := c.doAPI(ctx, http.MethodGet, "/api/v1/followed_tags", nil, &followedTags, pg)
if err != nil {
return nil, err
}
return followedTags, nil
}

View File

@ -697,3 +697,92 @@ func TestGetMutes(t *testing.T) {
t.Fatalf("want %q but %q", "bar", mutes[1].Username) t.Fatalf("want %q but %q", "bar", mutes[1].Username)
} }
} }
func TestGetFollowedTags(t *testing.T) {
canErr := true
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if canErr {
canErr = false
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, `[
{
"name": "Test1",
"url": "http://mastodon.example/tags/test1",
"history": [
{
"day": "1668211200",
"accounts": "0",
"uses": "0"
},
{
"day": "1668124800",
"accounts": "0",
"uses": "0"
},
{
"day": "1668038400",
"accounts": "0",
"uses": "0"
}
],
"following": true
},
{
"name": "Test2",
"url": "http://mastodon.example/tags/test2",
"history": [
{
"day": "1668211200",
"accounts": "0",
"uses": "0"
}
],
"following": true
}
]`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
_, err := client.GetFollowedTags(context.Background(), nil)
if err == nil {
t.Fatalf("should be fail: %v", err)
}
followedTags, err := client.GetFollowedTags(context.Background(), nil)
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if len(followedTags) != 2 {
t.Fatalf("result should be two: %d", len(followedTags))
}
if followedTags[0].Name != "Test1" {
t.Fatalf("want %q but %q", "Test1", followedTags[0].Name)
}
if followedTags[0].URL != "http://mastodon.example/tags/test1" {
t.Fatalf("want %q but got %q", "http://mastodon.example/tags/test1", followedTags[0].URL)
}
if !followedTags[0].Following {
t.Fatalf("want following, but got false")
}
if 3 != len(followedTags[0].History){
t.Fatalf("expecting first tag history length to be %d but got %d", 3, len(followedTags[0].History))
}
if followedTags[1].Name != "Test2" {
t.Fatalf("want %q but %q", "Test2", followedTags[1].Name)
}
if followedTags[1].URL != "http://mastodon.example/tags/test2" {
t.Fatalf("want %q but got %q", "http://mastodon.example/tags/test2", followedTags[1].URL)
}
if !followedTags[1].Following {
t.Fatalf("want following, but got false")
}
if 1 != len(followedTags[1].History){
t.Fatalf("expecting first tag history length to be %d but got %d", 1, len(followedTags[1].History))
}
}

View File

@ -9,7 +9,6 @@ require (
github.com/fatih/color v1.13.0 github.com/fatih/color v1.13.0
github.com/mattn/go-mastodon v0.0.4 github.com/mattn/go-mastodon v0.0.4
github.com/mattn/go-tty v0.0.4 github.com/mattn/go-tty v0.0.4
github.com/urfave/cli v1.13.0 github.com/urfave/cli/v2 v2.23.5
github.com/urfave/cli/v2 v2.23.5 // indirect
golang.org/x/net v0.0.0-20220531201128-c960675eff93 golang.org/x/net v0.0.0-20220531201128-c960675eff93
) )

View File

@ -24,8 +24,6 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y= github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y=
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE=
github.com/urfave/cli v1.13.0 h1:kkpCmfxnnnWIie2rCljcvaVrNYmsFq1ynTJH5kn1Ip4=
github.com/urfave/cli v1.13.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw= github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw=
github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=

View File

@ -258,7 +258,7 @@ func makeApp() *cli.App {
{ {
Name: "timeline-tag", Name: "timeline-tag",
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.BoolFlag{ &cli.BoolFlag{
Name: "local", Name: "local",
Usage: "local tags only", Usage: "local tags only",
}, },

6
go.work 100644
View File

@ -0,0 +1,6 @@
go 1.19
use (
.
./cmd/mstdn
)