mirror of
https://github.com/adulau/mastodon-markdown-archive.git
synced 2024-11-21 09:27:05 +00:00
Split into separate files
This commit is contained in:
parent
f97a0e47af
commit
3cf2b77edb
5 changed files with 214 additions and 198 deletions
46
client/account.go
Normal file
46
client/account.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Account struct {
|
||||
Id string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Acct string `json:"acct"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Locked bool `json:"locked"`
|
||||
Bot bool `json:"bot"`
|
||||
Discoverable bool `json:"discoverable"`
|
||||
Group bool `json:"group"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Note string `json:"note"`
|
||||
URL string `json:"url"`
|
||||
URI string `json:"uri"`
|
||||
Avatar string `json:"avatar"`
|
||||
AvatarStatic string `json:"avatar_static"`
|
||||
Header string `json:"header"`
|
||||
HeaderStatic string `json:"header_static"`
|
||||
FollowersCount int `json:"followers_count"`
|
||||
FollowingCount int `json:"following_count"`
|
||||
StatusesCount int `json:"statuses_count"`
|
||||
LastStatusAt string `json:"last_status_at"`
|
||||
}
|
||||
|
||||
func FetchAccount(baseURL string, handle string) (Account, error) {
|
||||
var account Account
|
||||
lookupUrl := fmt.Sprintf(
|
||||
"%s/api/v1/accounts/lookup?acct=%s",
|
||||
baseURL,
|
||||
handle,
|
||||
)
|
||||
|
||||
err := Fetch(lookupUrl, &account)
|
||||
|
||||
if err != nil {
|
||||
return account, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
25
client/api.go
Normal file
25
client/api.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func Fetch(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
|
||||
}
|
200
client/client.go
200
client/client.go
|
@ -1,15 +1,9 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
|
@ -24,74 +18,6 @@ type Client struct {
|
|||
output []int
|
||||
}
|
||||
|
||||
type Account struct {
|
||||
Id string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Acct string `json:"acct"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Locked bool `json:"locked"`
|
||||
Bot bool `json:"bot"`
|
||||
Discoverable bool `json:"discoverable"`
|
||||
Group bool `json:"group"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Note string `json:"note"`
|
||||
URL string `json:"url"`
|
||||
URI string `json:"uri"`
|
||||
Avatar string `json:"avatar"`
|
||||
AvatarStatic string `json:"avatar_static"`
|
||||
Header string `json:"header"`
|
||||
HeaderStatic string `json:"header_static"`
|
||||
FollowersCount int `json:"followers_count"`
|
||||
FollowingCount int `json:"following_count"`
|
||||
StatusesCount int `json:"statuses_count"`
|
||||
LastStatusAt string `json:"last_status_at"`
|
||||
}
|
||||
|
||||
type MediaAttachment struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
Description string `json:"description"`
|
||||
Id string `json:"id"`
|
||||
Path string
|
||||
}
|
||||
|
||||
type Application struct {
|
||||
Name string `json:"name"`
|
||||
Website string `json:"website"`
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Id string `json:"id"`
|
||||
Visibility string `json:"visibility"`
|
||||
InReplyToId string `json:"in_reply_to_id"`
|
||||
InReplyToAccountId string `json:"in_reply_to_account_id"`
|
||||
Sensitive bool `json:"sensitive"`
|
||||
SpoilerText string `json:"spoiler_text"`
|
||||
Language string `json:"language"`
|
||||
URI string `json:"uri"`
|
||||
URL string `json:"url"`
|
||||
Application Application `json:"application"`
|
||||
Content string `json:"content"`
|
||||
MediaAttachments []MediaAttachment `json:"media_attachments"`
|
||||
RepliesCount int `json:"replies_count"`
|
||||
ReblogsCount int `json:"reblogs_count"`
|
||||
FavoritesCount int `json:"favourites_count"`
|
||||
Pinned bool `json:"pinned"`
|
||||
Tags []Tag `json:"tags"`
|
||||
Favourited bool `json:"favourited"`
|
||||
Reblogged bool `json:"reblogged"`
|
||||
Muted bool `json:"muted"`
|
||||
Bookmarked bool `json:"bookmarked"`
|
||||
Account Account `json:"account"`
|
||||
descendants []*Post
|
||||
}
|
||||
|
||||
type PostsFilter struct {
|
||||
ExcludeReplies bool
|
||||
ExcludeReblogs bool
|
||||
|
@ -113,13 +39,13 @@ func New(userURL string, filters PostsFilter, threaded bool) (Client, error) {
|
|||
acc := strings.TrimPrefix(parsedURL.Path, "/")
|
||||
handle := strings.TrimPrefix(acc, "@")
|
||||
|
||||
account, err := getAccount(baseURL, handle)
|
||||
account, err := FetchAccount(baseURL, handle)
|
||||
|
||||
if err != nil {
|
||||
return client, err
|
||||
}
|
||||
|
||||
posts, err := getPosts(baseURL, account.Id, filters)
|
||||
posts, err := FetchPosts(baseURL, account.Id, filters)
|
||||
|
||||
if err != nil {
|
||||
return client, err
|
||||
|
@ -143,7 +69,7 @@ func New(userURL string, filters PostsFilter, threaded bool) (Client, error) {
|
|||
client.generateReplies()
|
||||
} else {
|
||||
for i := range client.posts {
|
||||
client.output = append(client.output, i)
|
||||
client.output = append(client.output, i)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,14 +90,6 @@ func (c Client) Posts() []*Post {
|
|||
return p
|
||||
}
|
||||
|
||||
func (p Post) ShouldSkip() bool {
|
||||
return p.Visibility != "public"
|
||||
}
|
||||
|
||||
func (p Post) Descendants() []*Post {
|
||||
return p.descendants
|
||||
}
|
||||
|
||||
func (c *Client) populateIdMap() {
|
||||
for i, post := range c.posts {
|
||||
c.postIdMap[post.Id] = i
|
||||
|
@ -203,115 +121,3 @@ func (c *Client) generateReplies() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPosts(baseURL string, accountId string, filters PostsFilter) ([]Post, error) {
|
||||
var posts []Post
|
||||
|
||||
queryValues := url.Values{}
|
||||
|
||||
if filters.ExcludeReplies {
|
||||
queryValues.Add("exclude_replies", strconv.Itoa(1))
|
||||
}
|
||||
|
||||
if filters.ExcludeReblogs {
|
||||
queryValues.Add("exclude_reblogs", strconv.Itoa(1))
|
||||
}
|
||||
|
||||
if filters.SinceId != "" {
|
||||
queryValues.Add("since_id", filters.SinceId)
|
||||
}
|
||||
|
||||
if filters.MaxId != "" {
|
||||
queryValues.Add("max_id", filters.MaxId)
|
||||
}
|
||||
|
||||
if filters.MinId != "" {
|
||||
queryValues.Add("min_id", filters.MinId)
|
||||
}
|
||||
|
||||
queryValues.Add("limit", strconv.Itoa(filters.Limit))
|
||||
|
||||
query := fmt.Sprintf("?%s", queryValues.Encode())
|
||||
|
||||
postsUrl := fmt.Sprintf(
|
||||
"%s/api/v1/accounts/%s/statuses/%s",
|
||||
baseURL,
|
||||
accountId,
|
||||
query,
|
||||
)
|
||||
|
||||
log.Println(fmt.Sprintf("Fetching posts from %s", postsUrl))
|
||||
|
||||
if err := get(postsUrl, &posts); err != nil {
|
||||
return posts, err
|
||||
}
|
||||
|
||||
return posts, nil
|
||||
}
|
||||
|
||||
func getAccount(baseURL string, handle string) (Account, error) {
|
||||
var account Account
|
||||
lookupUrl := fmt.Sprintf(
|
||||
"%s/api/v1/accounts/lookup?acct=%s",
|
||||
baseURL,
|
||||
handle,
|
||||
)
|
||||
|
||||
err := get(lookupUrl, &account)
|
||||
|
||||
if err != nil {
|
||||
return account, err
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (p Post) AllTags() []Tag {
|
||||
var tags []Tag
|
||||
|
||||
for _, tag := range p.Tags {
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
|
||||
for _, descendant := range p.descendants {
|
||||
for _, tag := range descendant.Tags {
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
}
|
||||
|
||||
return tags
|
||||
}
|
||||
|
||||
func (p Post) AllMedia() []MediaAttachment {
|
||||
var media []MediaAttachment
|
||||
|
||||
for _, item := range p.MediaAttachments {
|
||||
media = append(media, item)
|
||||
}
|
||||
|
||||
for _, descendant := range p.descendants {
|
||||
for _, item := range descendant.MediaAttachments {
|
||||
media = append(media, item)
|
||||
}
|
||||
}
|
||||
|
||||
return media
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
139
client/post.go
Normal file
139
client/post.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MediaAttachment struct {
|
||||
Type string `json:"type"`
|
||||
URL string `json:"url"`
|
||||
Description string `json:"description"`
|
||||
Id string `json:"id"`
|
||||
Path string
|
||||
}
|
||||
|
||||
type Application struct {
|
||||
Name string `json:"name"`
|
||||
Website string `json:"website"`
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Id string `json:"id"`
|
||||
Visibility string `json:"visibility"`
|
||||
InReplyToId string `json:"in_reply_to_id"`
|
||||
InReplyToAccountId string `json:"in_reply_to_account_id"`
|
||||
Sensitive bool `json:"sensitive"`
|
||||
SpoilerText string `json:"spoiler_text"`
|
||||
Language string `json:"language"`
|
||||
URI string `json:"uri"`
|
||||
URL string `json:"url"`
|
||||
Application Application `json:"application"`
|
||||
Content string `json:"content"`
|
||||
MediaAttachments []MediaAttachment `json:"media_attachments"`
|
||||
RepliesCount int `json:"replies_count"`
|
||||
ReblogsCount int `json:"reblogs_count"`
|
||||
FavoritesCount int `json:"favourites_count"`
|
||||
Pinned bool `json:"pinned"`
|
||||
Tags []Tag `json:"tags"`
|
||||
Favourited bool `json:"favourited"`
|
||||
Reblogged bool `json:"reblogged"`
|
||||
Muted bool `json:"muted"`
|
||||
Bookmarked bool `json:"bookmarked"`
|
||||
Account Account `json:"account"`
|
||||
descendants []*Post
|
||||
}
|
||||
|
||||
func (p Post) ShouldSkip() bool {
|
||||
return p.Visibility != "public"
|
||||
}
|
||||
|
||||
func (p Post) Descendants() []*Post {
|
||||
return p.descendants
|
||||
}
|
||||
|
||||
func (p Post) AllTags() []Tag {
|
||||
var tags []Tag
|
||||
|
||||
for _, tag := range p.Tags {
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
|
||||
for _, descendant := range p.descendants {
|
||||
for _, tag := range descendant.Tags {
|
||||
tags = append(tags, tag)
|
||||
}
|
||||
}
|
||||
|
||||
return tags
|
||||
}
|
||||
|
||||
func (p Post) AllMedia() []MediaAttachment {
|
||||
var media []MediaAttachment
|
||||
|
||||
for _, item := range p.MediaAttachments {
|
||||
media = append(media, item)
|
||||
}
|
||||
|
||||
for _, descendant := range p.descendants {
|
||||
for _, item := range descendant.MediaAttachments {
|
||||
media = append(media, item)
|
||||
}
|
||||
}
|
||||
|
||||
return media
|
||||
}
|
||||
|
||||
func FetchPosts(baseURL string, accountId string, filters PostsFilter) ([]Post, error) {
|
||||
var posts []Post
|
||||
|
||||
queryValues := url.Values{}
|
||||
|
||||
if filters.ExcludeReplies {
|
||||
queryValues.Add("exclude_replies", strconv.Itoa(1))
|
||||
}
|
||||
|
||||
if filters.ExcludeReblogs {
|
||||
queryValues.Add("exclude_reblogs", strconv.Itoa(1))
|
||||
}
|
||||
|
||||
if filters.SinceId != "" {
|
||||
queryValues.Add("since_id", filters.SinceId)
|
||||
}
|
||||
|
||||
if filters.MaxId != "" {
|
||||
queryValues.Add("max_id", filters.MaxId)
|
||||
}
|
||||
|
||||
if filters.MinId != "" {
|
||||
queryValues.Add("min_id", filters.MinId)
|
||||
}
|
||||
|
||||
queryValues.Add("limit", strconv.Itoa(filters.Limit))
|
||||
|
||||
query := fmt.Sprintf("?%s", queryValues.Encode())
|
||||
|
||||
postsUrl := fmt.Sprintf(
|
||||
"%s/api/v1/accounts/%s/statuses/%s",
|
||||
baseURL,
|
||||
accountId,
|
||||
query,
|
||||
)
|
||||
|
||||
log.Println(fmt.Sprintf("Fetching posts from %s", postsUrl))
|
||||
|
||||
if err := Fetch(postsUrl, &posts); err != nil {
|
||||
return posts, err
|
||||
}
|
||||
|
||||
return posts, nil
|
||||
}
|
|
@ -46,7 +46,7 @@ func New(dir string) (FileWriter, error) {
|
|||
}
|
||||
|
||||
return FileWriter{
|
||||
dir: absDir,
|
||||
dir: absDir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue