149 lines
3.9 KiB
Go
149 lines
3.9 KiB
Go
package services
|
|
|
|
import (
|
|
"CatsOfMastodonBotGo/internal/models"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
type PostService struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// Constructor
|
|
func NewPostService(db *gorm.DB) *PostService {
|
|
return &PostService{db: db}
|
|
}
|
|
|
|
func (*PostService) GetPostsFromApi(ctx context.Context, tag string, instance string) (error, []models.Post) {
|
|
var requestUrl = instance + "/api/v1/timelines/tag/" + tag + "?limit=40"
|
|
req, err := http.NewRequestWithContext(ctx, "GET", requestUrl, nil)
|
|
if err != nil {
|
|
return err, nil
|
|
}
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return err, nil
|
|
}
|
|
if resp.StatusCode != 200 || strings.Split(strings.ToLower(resp.Header.Get("Content-Type")), ";")[0] != "application/json" {
|
|
return fmt.Errorf("Status code:", resp.StatusCode, " Content-Type:", resp.Header.Get("Content-Type")), nil
|
|
}
|
|
|
|
var posts []models.Post = nil
|
|
err = json.NewDecoder(resp.Body).Decode(&posts)
|
|
if err != nil {
|
|
return err, nil
|
|
}
|
|
// defer: it basically means "do this later when the function returns"
|
|
defer resp.Body.Close()
|
|
if posts == nil {
|
|
return fmt.Errorf("no posts found for tag %s on instance %s", tag, instance), nil
|
|
}
|
|
return nil, posts
|
|
}
|
|
|
|
func (ps *PostService) GetExistingPostIds() []string {
|
|
var existingPostIds []string
|
|
ps.db.Model(&models.Post{}).Pluck("id", &existingPostIds)
|
|
return existingPostIds
|
|
}
|
|
|
|
func (ps *PostService) GetExistingAccountIds() []string {
|
|
var existingAccountIds []string
|
|
ps.db.Model(&models.Account{}).Pluck("acc_id", &existingAccountIds)
|
|
return existingAccountIds
|
|
}
|
|
|
|
|
|
func (*PostService) GetNewPosts(existingPostIds []string, posts []models.Post) []models.Post {
|
|
var newPosts []models.Post = nil
|
|
for _, post := range posts {
|
|
if !arrayContains(existingPostIds, post.ID) && len(post.Attachments) > 0 && !post.Account.IsBot {
|
|
var allImageMedia = true
|
|
for _, attachment := range post.Attachments {
|
|
if attachment.Type != "image" {
|
|
allImageMedia = false
|
|
break
|
|
}
|
|
} // Inefficient but anyways
|
|
if allImageMedia {
|
|
newPosts = append(newPosts, post)
|
|
}
|
|
}
|
|
}
|
|
return newPosts
|
|
}
|
|
|
|
func (*PostService) GetNewAccounts(existingAccountIds []string, posts []models.Post) []models.Account {
|
|
var newAccounts []models.Account = nil
|
|
for _, post := range posts {
|
|
if !arrayContains(existingAccountIds, post.Account.AccId) {
|
|
newAccounts = append(newAccounts, post.Account)
|
|
}
|
|
}
|
|
return newAccounts
|
|
}
|
|
|
|
func (ps *PostService) InsertNewPosts(newPosts []models.Post) int {
|
|
return int(ps.db.Create(&newPosts).RowsAffected)
|
|
}
|
|
|
|
func (ps *PostService) InsertNewAccounts(newAccounts []models.Account) int {
|
|
return int(ps.db.Clauses(clause.OnConflict{UpdateAll: true}).Create(&newAccounts).RowsAffected)
|
|
}
|
|
|
|
// From this point on, its for the api endpoints
|
|
|
|
func (ps *PostService) GetRandomPost() models.Post {
|
|
var post models.Post
|
|
ps.db.
|
|
Preload("Account").
|
|
Preload("Attachments", "approved = ?", true).
|
|
Order("RANDOM()").
|
|
First(&post)
|
|
if len(post.Attachments) > 0 {
|
|
post.Attachments = []models.MediaAttachment{post.Attachments[0]}
|
|
}
|
|
return post
|
|
}
|
|
|
|
func (ps *PostService) ApproveMedia(mediaId string) bool {
|
|
return ps.db.Model(&models.MediaAttachment{}).
|
|
Where("id = ?", mediaId).
|
|
Update("approved", true).RowsAffected > 0
|
|
}
|
|
|
|
func (ps *PostService) RejectMedia(mediaId string) bool {
|
|
return ps.db.Model(&models.MediaAttachment{}).
|
|
Where("id = ?", mediaId).
|
|
Update("rejected", true).RowsAffected > 0
|
|
}
|
|
|
|
// Get a post which approve and rejet are false (For admin panel)
|
|
func (ps *PostService) GetMedia() models.MediaAttachment {
|
|
var media models.MediaAttachment
|
|
ps.db.Model(&models.MediaAttachment{}).
|
|
Where("approved = ?", false).
|
|
Where("rejected = ?", false).
|
|
Order("RANDOM()").
|
|
First(&media)
|
|
return media
|
|
}
|
|
|
|
|
|
func arrayContains(arr []string, str string) bool {
|
|
for _, a := range arr {
|
|
if a == str {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|