From 3b7bf239ba40e4e2bbac7fb05f639487f9cc06bd Mon Sep 17 00:00:00 2001 From: Gabriel Garrido Date: Sun, 21 Apr 2024 15:08:09 +0200 Subject: [PATCH] Fetch user account id and posts --- LICENSE | 2 +- client/client.go | 111 +++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 +++ main.go | 30 +++++++++++++ 4 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 client/client.go create mode 100644 go.mod create mode 100644 main.go diff --git a/LICENSE b/LICENSE index 71a6faf..7fc8151 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 gabriel +Copyright (c) 2024 Gabriel Garrido Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..cd83d37 --- /dev/null +++ b/client/client.go @@ -0,0 +1,111 @@ +package client + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" +) + +type Client struct { + handle string + baseURL string +} + +type Account struct { + Id string `json:"id"` +} + +type MediaAttachment struct { + Type string `json:"type"` + Url string `json:"url"` + Description string `json:"description"` +} + +type Post struct { + CreatedAt time.Time `json:"created_at"` + Id string `json:"id"` + Visibility string `json:"visibility"` + InReplyToAccountId string `json:"in_reply_to_account_id"` + URI string `json:"uri"` + Content string `json:"content"` + MediaAttachments []MediaAttachment `json:"media_attachments"` +} + +func New(userURL string) (Client, error) { + var client Client + parsedURL, err := url.Parse(userURL) + + if err != nil { + return client, fmt.Errorf("error parsing user url: %w", err) + } + + baseURL := fmt.Sprintf("%s://%s", parsedURL.Scheme, parsedURL.Host) + acc := strings.TrimPrefix(parsedURL.Path, "/") + handle := strings.TrimPrefix(acc, "@") + + return Client{ + baseURL: baseURL, + handle: handle, + }, nil +} + +func (c Client) GetPosts(params string) ([]Post, error) { + var posts []Post + account, err := c.getAccount() + + if err != nil { + return posts, err + } + + postsUrl := fmt.Sprintf( + "%s/api/v1/accounts/%s/statuses/%s", + c.baseURL, + account.Id, + params, + ) + + if err := get(postsUrl, &posts); err != nil { + return posts, err + } + + return posts, nil +} + +func (c Client) getAccount() (Account, error) { + var account Account + lookupUrl := fmt.Sprintf( + "%s/api/v1/accounts/lookup?acct=%s", + c.baseURL, + c.handle, + ) + + err := get(lookupUrl, &account) + + if err != nil { + return account, err + } + + return account, nil +} + +func get(requestUrl string, variable interface{}) error { + res, err := http.Get(requestUrl) + + if err != nil { + return err + } + + defer res.Body.Close() + + body, err := io.ReadAll(res.Body) + + if err := json.Unmarshal(body, variable); err != nil { + return err + } + + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..238e96a --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.hq.ggpsv.com/gabriel/mastodon-pesos + +go 1.21.6 + +replace git.hq.ggpsv.com/gabriel/mastodon-pesos/client => ./client diff --git a/main.go b/main.go new file mode 100644 index 0000000..31eb110 --- /dev/null +++ b/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "flag" + "fmt" + "git.hq.ggpsv.com/gabriel/mastodon-pesos/client" + "log" +) + +func main() { + user := flag.String("user", "", "URL of User's Mastodon account whose toots will be fetched") + + flag.Parse() + + client, err := client.New(*user) + + if err != nil { + log.Panicln(fmt.Errorf("error instantiating client: %w", err)) + } + + posts, err := client.GetPosts("?exclude_replies=1&exclude_reblogs=1&limit=10") + + if err != nil { + log.Panicln(err) + } + + for _, post := range posts { + log.Println(post.Id) + } +}