306 lines
8.4 KiB
Go
306 lines
8.4 KiB
Go
package model
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
|
|
)
|
|
|
|
type Status struct {
|
|
Account Account `json:"account"`
|
|
Application Application `json:"application"`
|
|
Bookmarked bool `json:"bookmarked"`
|
|
Card Card `json:"card"`
|
|
Content string `json:"content"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Emojis []Emoji `json:"emojis"`
|
|
Favourited bool `json:"favourited"`
|
|
FavouritesCount int `json:"favourites_count"`
|
|
ID string `json:"id"`
|
|
InReplyToAccountID string `json:"in_reply_to_account_id"`
|
|
InReplyToID string `json:"in_reply_to_id"`
|
|
Language string `json:"language"`
|
|
MediaAttachments []Attachment `json:"media_attachments"`
|
|
Mentions []Mention `json:"mentions"`
|
|
Muted bool `json:"muted"`
|
|
Pinned bool `json:"pinned"`
|
|
Poll Poll `json:"poll"`
|
|
Reblog *StatusReblogged `json:"reblog"`
|
|
Reblogged bool `json:"reblogged"`
|
|
ReblogsCount int `json:"reblogs_count"`
|
|
RepliesCount int `json:"replies_count"`
|
|
Sensitive bool `json:"sensitive"`
|
|
SpolierText string `json:"spoiler_text"`
|
|
Tags []Tag `json:"tags"`
|
|
Text string `json:"text"`
|
|
URI string `json:"uri"`
|
|
URL string `json:"url"`
|
|
Visibility StatusVisibility `json:"visibility"`
|
|
}
|
|
|
|
type Card struct {
|
|
AuthorName string `json:"author_name"`
|
|
AuthorURL string `json:"author_url"`
|
|
Blurhash string `json:"blurhash"`
|
|
Description string `json:"description"`
|
|
EmbedURL string `json:"embed_url"`
|
|
HTML string `json:"html"`
|
|
Image string `json:"image"`
|
|
ProviderName string `json:"provider_name"`
|
|
ProviderURL string `json:"provider_url"`
|
|
Title string `json:"title"`
|
|
Type string `json:"type"`
|
|
URL string `json:"url"`
|
|
Height int `json:"height"`
|
|
Width int `json:"width"`
|
|
}
|
|
|
|
type Mention struct {
|
|
Acct string `json:"acct"`
|
|
ID string `json:"id"`
|
|
URL string `json:"url"`
|
|
Username string `json:"username"`
|
|
}
|
|
|
|
type Poll struct {
|
|
Emojis []Emoji `json:"emojis"`
|
|
Expired bool `json:"expired"`
|
|
Voted bool `json:"voted"`
|
|
Multiple bool `json:"multiple"`
|
|
ExpiredAt time.Time `json:"expires_at"`
|
|
ID string `json:"id"`
|
|
OwnVotes []int `json:"own_votes"`
|
|
VotersCount int `json:"voters_count"`
|
|
VotesCount int `json:"votes_count"`
|
|
Options []PollOption `json:"options"`
|
|
}
|
|
|
|
type PollOption struct {
|
|
Title string `json:"title"`
|
|
VotesCount string `json:"votes_count"`
|
|
}
|
|
|
|
type StatusReblogged struct {
|
|
Account Account `json:"account"`
|
|
Application Application `json:"application"`
|
|
Bookmarked bool `json:"bookmarked"`
|
|
Card Card `json:"card"`
|
|
Content string `json:"content"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Emojis []Emoji `json:"emojis"`
|
|
Favourited bool `json:"favourited"`
|
|
FavouritesCount int `json:"favourites_count"`
|
|
ID string `json:"id"`
|
|
InReplyToAccountID string `json:"in_reply_to_account_id"`
|
|
InReplyToID string `json:"in_reply_to_id"`
|
|
Language string `json:"language"`
|
|
MediaAttachments []Attachment `json:"media_attachments"`
|
|
Mentions []Mention `json:"mentions"`
|
|
Muted bool `json:"muted"`
|
|
Pinned bool `json:"pinned"`
|
|
Poll Poll `json:"poll"`
|
|
Reblogged bool `json:"reblogged"`
|
|
RebloggsCount int `json:"reblogs_count"`
|
|
RepliesCount int `json:"replies_count"`
|
|
Sensitive bool `json:"sensitive"`
|
|
SpolierText string `json:"spoiler_text"`
|
|
Tags []Tag `json:"tags"`
|
|
Text string `json:"text"`
|
|
URI string `json:"uri"`
|
|
URL string `json:"url"`
|
|
Visibility StatusVisibility `json:"visibility"`
|
|
}
|
|
|
|
type Tag struct {
|
|
History []any `json:"history"`
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
type Attachment struct {
|
|
Meta MediaMeta `json:"meta"`
|
|
Blurhash string `json:"blurhash"`
|
|
Description string `json:"description"`
|
|
ID string `json:"id"`
|
|
PreviewRemoteURL string `json:"preview_remote_url"`
|
|
PreviewURL string `json:"preview_url"`
|
|
RemoteURL string `json:"remote_url"`
|
|
TextURL string `json:"text_url"`
|
|
Type string `json:"type"`
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
type MediaMeta struct {
|
|
Focus MediaFocus `json:"focus"`
|
|
Original MediaDimensions `json:"original"`
|
|
Small MediaDimensions `json:"small"`
|
|
}
|
|
|
|
type MediaFocus struct {
|
|
X float64 `json:"x"`
|
|
Y float64 `json:"y"`
|
|
}
|
|
|
|
type MediaDimensions struct {
|
|
Aspect float64 `json:"aspect"`
|
|
Bitrate int `json:"bitrate"`
|
|
Duration float64 `json:"duration"`
|
|
FrameRate string `json:"frame_rate"`
|
|
Size string `json:"size"`
|
|
Height int `json:"height"`
|
|
Width int `json:"width"`
|
|
}
|
|
|
|
func (s Status) String() string {
|
|
format := `
|
|
%s (@%s)
|
|
|
|
%s
|
|
%s
|
|
%s
|
|
%s
|
|
|
|
%s
|
|
%s
|
|
|
|
%s
|
|
Boosts: %d
|
|
Likes: %d
|
|
Replies: %d
|
|
|
|
%s
|
|
%s
|
|
|
|
%s
|
|
%s
|
|
`
|
|
|
|
return fmt.Sprintf(
|
|
format,
|
|
utilities.DisplayNameFormat(s.Account.DisplayName), s.Account.Username,
|
|
utilities.HeaderFormat("CONTENT:"),
|
|
utilities.WrapLines(utilities.StripHTMLTags(s.Content), "\n ", 80),
|
|
utilities.HeaderFormat("STATUS ID:"),
|
|
s.ID,
|
|
utilities.HeaderFormat("CREATED AT:"),
|
|
utilities.FormatTime(s.CreatedAt),
|
|
utilities.HeaderFormat("STATS:"),
|
|
s.ReblogsCount,
|
|
s.FavouritesCount,
|
|
s.RepliesCount,
|
|
utilities.HeaderFormat("VISIBILITY:"),
|
|
s.Visibility,
|
|
utilities.HeaderFormat("URL:"),
|
|
s.URL,
|
|
)
|
|
}
|
|
|
|
type StatusVisibility int
|
|
|
|
const (
|
|
StatusVisibilityPublic StatusVisibility = iota
|
|
StatusVisibilityPrivate
|
|
StatusVisibilityUnlisted
|
|
StatusVisibilityMutualsOnly
|
|
StatusVisibilityDirect
|
|
StatusVisibilityUnknown
|
|
)
|
|
|
|
func (s StatusVisibility) String() string {
|
|
switch s {
|
|
case StatusVisibilityPublic:
|
|
return "public"
|
|
case StatusVisibilityPrivate:
|
|
return "private"
|
|
case StatusVisibilityUnlisted:
|
|
return "unlisted"
|
|
case StatusVisibilityMutualsOnly:
|
|
return "mutuals_only"
|
|
case StatusVisibilityDirect:
|
|
return "direct"
|
|
}
|
|
|
|
return "unknown"
|
|
}
|
|
|
|
func ParseStatusVisibility(value string) StatusVisibility {
|
|
switch value {
|
|
case "public":
|
|
return StatusVisibilityPublic
|
|
case "private":
|
|
return StatusVisibilityPrivate
|
|
case "unlisted":
|
|
return StatusVisibilityUnlisted
|
|
case "mutuals_only":
|
|
return StatusVisibilityMutualsOnly
|
|
case "direct":
|
|
return StatusVisibilityDirect
|
|
}
|
|
|
|
return StatusVisibilityUnknown
|
|
}
|
|
|
|
func (s StatusVisibility) MarshalJSON() ([]byte, error) {
|
|
value := s.String()
|
|
if value == "unknown" {
|
|
return nil, fmt.Errorf("%q is not a valid status visibility", value)
|
|
}
|
|
|
|
return json.Marshal(value)
|
|
}
|
|
|
|
func (s *StatusVisibility) UnmarshalJSON(data []byte) error {
|
|
var (
|
|
value string
|
|
err error
|
|
)
|
|
|
|
if err = json.Unmarshal(data, &value); err != nil {
|
|
return fmt.Errorf("unable to unmarshal the data; %w", err)
|
|
}
|
|
|
|
*s = ParseStatusVisibility(value)
|
|
|
|
return nil
|
|
}
|
|
|
|
type StatusContentType int
|
|
|
|
const (
|
|
StatusContentTypePlainText StatusContentType = iota
|
|
StatusContentTypeMarkdown
|
|
StatusContentTypeUnknown
|
|
)
|
|
|
|
func (s StatusContentType) String() string {
|
|
switch s {
|
|
case StatusContentTypePlainText:
|
|
return "text/plain"
|
|
case StatusContentTypeMarkdown:
|
|
return "text/markdown"
|
|
}
|
|
|
|
return "unknown"
|
|
}
|
|
|
|
func ParseStatusContentType(value string) StatusContentType {
|
|
switch value {
|
|
case "plain", "text/plain":
|
|
return StatusContentTypePlainText
|
|
case "markdown", "text/markdown":
|
|
return StatusContentTypeMarkdown
|
|
}
|
|
|
|
return StatusContentTypeUnknown
|
|
}
|
|
|
|
func (s StatusContentType) MarshalJSON() ([]byte, error) {
|
|
value := s.String()
|
|
if value == "unknown" {
|
|
return nil, fmt.Errorf("%q is not a valid status content type", value)
|
|
}
|
|
|
|
return json.Marshal(value)
|
|
}
|