From f7bf818d29393ceaccf4d2906557351fa6a4f49f Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Sat, 7 May 2022 21:21:38 -0700 Subject: added error func and general cleanup/organization --- activitypub/actor.go | 665 ++++++++++++++------------------------------------- 1 file changed, 179 insertions(+), 486 deletions(-) (limited to 'activitypub/actor.go') diff --git a/activitypub/actor.go b/activitypub/actor.go index bec0bce..120c9fd 100644 --- a/activitypub/actor.go +++ b/activitypub/actor.go @@ -13,10 +13,7 @@ import ( "errors" "fmt" "io/ioutil" - "log" - "net/http" "os" - "regexp" "strings" "github.com/FChannel0/FChannel-Server/config" @@ -24,54 +21,23 @@ import ( "github.com/gofiber/fiber/v2" ) -func CreateNewActor(board string, prefName string, summary string, authReq []string, restricted bool) *Actor { - actor := new(Actor) - - var path string - if board == "" { - path = config.Domain - actor.Name = "main" - } else { - path = config.Domain + "/" + board - actor.Name = board - } - - actor.Type = "Group" - actor.Id = fmt.Sprintf("%s", path) - actor.Following = fmt.Sprintf("%s/following", actor.Id) - actor.Followers = fmt.Sprintf("%s/followers", actor.Id) - actor.Inbox = fmt.Sprintf("%s/inbox", actor.Id) - actor.Outbox = fmt.Sprintf("%s/outbox", actor.Id) - actor.PreferredUsername = prefName - actor.Restricted = restricted - actor.Summary = summary - actor.AuthRequirement = authReq - - return actor -} - func (actor Actor) AddFollower(follower string) error { query := `insert into follower (id, follower) values ($1, $2)` _, err := config.DB.Exec(query, actor.Id, follower) - return err + return util.MakeError(err, "AddFollwer") } func (actor Actor) ActivitySign(signature string) (string, error) { - query := `select file from publicKeyPem where id=$1 ` + var file string - rows, err := config.DB.Query(query, actor.PublicKey.Id) - if err != nil { - return "", err + query := `select file from publicKeyPem where id=$1 ` + if err := config.DB.QueryRow(query, actor.PublicKey.Id).Scan(&file); err != nil { + return "", util.MakeError(err, "ActivitySign") } - defer rows.Close() - - var file string - rows.Next() - rows.Scan(&file) - file = strings.ReplaceAll(file, "public.pem", "private.pem") - _, err = os.Stat(file) + + _, err := os.Stat(file) if err != nil { fmt.Println(`\n Unable to locate private key. Now, this means that you are now missing the proof that you are the @@ -80,16 +46,16 @@ then your job is just as easy as generating a new keypair, but if this board is live, then you'll also have to convince the other owners to switch their public keys for you so that they will start accepting your posts from your board from this site. Good luck ;)`) - return "", errors.New("unable to locate private key") + return "", util.MakeError(err, "ActivitySign") } - publickey, err := ioutil.ReadFile(file) - if err != nil { - return "", err + var publickey []byte + + if publickey, err = ioutil.ReadFile(file); err != nil { + return "", util.MakeError(err, "ActivitySign") } block, _ := pem.Decode(publickey) - pub, _ := x509.ParsePKCS1PrivateKey(block.Bytes) rng := crand.Reader hashed := sha256.New() @@ -101,23 +67,21 @@ accepting your posts from your board from this site. Good luck ;)`) func (actor Actor) DeleteCache() error { query := `select id from cacheactivitystream where id in (select id from cacheactivitystream where actor=$1)` - rows, err := config.DB.Query(query, actor.Id) if err != nil { - return err + return util.MakeError(err, "DeleteCache") } defer rows.Close() - for rows.Next() { var obj ObjectBase if err := rows.Scan(&obj.Id); err != nil { - return err + return util.MakeError(err, "DeleteCache") } if err := obj.Delete(); err != nil { - return err + return util.MakeError(err, "DeleteCache") } } @@ -129,7 +93,7 @@ func (actor Actor) GetAutoSubscribe() (bool, error) { query := `select autosubscribe from actor where id=$1` if err := config.DB.QueryRow(query, actor.Id).Scan(&subscribed); err != nil { - return false, err + return false, util.MakeError(err, "GetAutoSubscribe") } return subscribed, nil @@ -140,10 +104,9 @@ func (actor Actor) GetCollectionType(nType string) (Collection, error) { var result []ObjectBase query := `select x.id, x.name, x.content, x.type, x.published, x.updated, x.attributedto, x.attachment, x.preview, x.actor, x.tripcode, x.sensitive from (select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor=$1 and id in (select id from replies where inreplyto='') and type=$2 union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type=$2 union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from cacheactivitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type=$2) as x order by x.updated desc` - rows, err := config.DB.Query(query, actor.Id, nType) if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionType") } defer rows.Close() @@ -158,7 +121,7 @@ func (actor Actor) GetCollectionType(nType string) (Collection, error) { post.Preview = &prev if err := rows.Scan(&post.Id, &post.Name, &post.Content, &post.Type, &post.Published, &post.Updated, &post.AttributedTo, &post.Attachment[0].Id, &post.Preview.Id, &actor.Id, &post.TripCode, &post.Sensitive); err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionType") } post.Actor = actor.Id @@ -167,21 +130,19 @@ func (actor Actor) GetCollectionType(nType string) (Collection, error) { post.Replies = replies - var err error - post.Replies.TotalItems, post.Replies.TotalImgs, err = post.GetRepliesCount() if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionType") } post.Attachment, err = post.Attachment[0].GetAttachment() if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionType") } post.Preview, err = post.Preview.GetPreview() if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionType") } result = append(result, post) @@ -197,10 +158,10 @@ func (actor Actor) GetCollectionTypeLimit(nType string, limit int) (Collection, var result []ObjectBase query := `select x.id, x.name, x.content, x.type, x.published, x.updated, x.attributedto, x.attachment, x.preview, x.actor, x.tripcode, x.sensitive from (select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor=$1 and id in (select id from replies where inreplyto='') and type=$2 union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type=$2 union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from cacheactivitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type=$2) as x order by x.updated desc limit $3` - rows, err := config.DB.Query(query, actor.Id, nType, limit) + if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionTypeLimit") } defer rows.Close() @@ -215,7 +176,7 @@ func (actor Actor) GetCollectionTypeLimit(nType string, limit int) (Collection, post.Preview = &prev if err := rows.Scan(&post.Id, &post.Name, &post.Content, &post.Type, &post.Published, &post.Updated, &post.AttributedTo, &post.Attachment[0].Id, &post.Preview.Id, &actor.Id, &post.TripCode, &post.Sensitive); err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionTypeLimit") } post.Actor = actor.Id @@ -224,20 +185,19 @@ func (actor Actor) GetCollectionTypeLimit(nType string, limit int) (Collection, post.Replies = replies - var err error post.Replies.TotalItems, post.Replies.TotalImgs, err = post.GetRepliesCount() if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionTypeLimit") } post.Attachment, err = post.Attachment[0].GetAttachment() if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionTypeLimit") } post.Preview, err = post.Preview.GetPreview() if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionTypeLimit") } result = append(result, post) @@ -252,18 +212,18 @@ func (actor Actor) GetFollow() ([]ObjectBase, error) { var followerCollection []ObjectBase query := `select follower from follower where id=$1` - rows, err := config.DB.Query(query, actor.Id) + if err != nil { - return followerCollection, err + return followerCollection, util.MakeError(err, "GetFollow") } - defer rows.Close() + defer rows.Close() for rows.Next() { var obj ObjectBase if err := rows.Scan(&obj.Id); err != nil { - return followerCollection, err + return followerCollection, util.MakeError(err, "GetFollow") } followerCollection = append(followerCollection, obj) @@ -277,7 +237,7 @@ func (actor Actor) GetFollowingTotal() (int, error) { query := `select count(following) from following where id=$1` if err := config.DB.QueryRow(query, actor.Id).Scan(&following); err != nil { - return following, err + return following, util.MakeError(err, "GetFollowingTotal") } return following, nil @@ -288,7 +248,7 @@ func (actor Actor) GetFollowersTotal() (int, error) { query := `select count(follower) from follower where id=$1` if err := config.DB.QueryRow(query, actor.Id).Scan(&followers); err != nil { - return followers, err + return followers, util.MakeError(err, "GetFollowersTotal") } return followers, nil @@ -301,18 +261,21 @@ func (actor Actor) GetFollowersResp(ctx *fiber.Ctx) error { following.AtContext.Context = "https://www.w3.org/ns/activitystreams" following.Type = "Collection" following.TotalItems, err = actor.GetFollowingTotal() + if err != nil { - return err + return util.MakeError(err, "GetFollowersResp") } following.Items, err = actor.GetFollow() + if err != nil { - return err + return util.MakeError(err, "GetFollowersResp") } enc, _ := json.MarshalIndent(following, "", "\t") ctx.Response().Header.Set("Content-Type", config.ActivityStreams) _, err = ctx.Write(enc) + return err } @@ -323,37 +286,40 @@ func (actor Actor) GetFollowingResp(ctx *fiber.Ctx) error { following.AtContext.Context = "https://www.w3.org/ns/activitystreams" following.Type = "Collection" following.TotalItems, err = actor.GetFollowingTotal() + if err != nil { - return err + return util.MakeError(err, "GetFollowingResp") } following.Items, err = actor.GetFollowing() + if err != nil { - return err + return util.MakeError(err, "GetFollowingResp") } enc, _ := json.MarshalIndent(following, "", "\t") ctx.Response().Header.Set("Content-Type", config.ActivityStreams) _, err = ctx.Write(enc) - return err + return util.MakeError(err, "GetFollowingResp") } func (actor Actor) GetFollowing() ([]ObjectBase, error) { var followingCollection []ObjectBase - query := `select following from following where id=$1` + query := `select following from following where id=$1` rows, err := config.DB.Query(query, actor.Id) + if err != nil { - return followingCollection, err + return followingCollection, util.MakeError(err, "GetFollowing") } - defer rows.Close() + defer rows.Close() for rows.Next() { var obj ObjectBase if err := rows.Scan(&obj.Id); err != nil { - return followingCollection, err + return followingCollection, util.MakeError(err, "GetFollowing") } followingCollection = append(followingCollection, obj) @@ -368,7 +334,7 @@ func (actor Actor) GetInfoResp(ctx *fiber.Ctx) error { _, err := ctx.Write(enc) - return err + return util.MakeError(err, "GetInfoResp") } func (actor Actor) GetCollection() (Collection, error) { @@ -376,10 +342,10 @@ func (actor Actor) GetCollection() (Collection, error) { var result []ObjectBase query := `select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor=$1 and id in (select id from replies where inreplyto='') and type='Note' order by updated desc` - rows, err := config.DB.Query(query, actor.Id) + if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollection") } defer rows.Close() @@ -394,34 +360,34 @@ func (actor Actor) GetCollection() (Collection, error) { post.Preview = &prev if err := rows.Scan(&post.Id, &post.Name, &post.Content, &post.Type, &post.Published, &post.Updated, &post.AttributedTo, &post.Attachment[0].Id, &post.Preview.Id, &actor.Id, &post.TripCode, &post.Sensitive); err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollection") } post.Actor = actor.Id - var postCnt int - var imgCnt int - post.Replies, postCnt, imgCnt, err = post.GetReplies() + post.Replies, post.Replies.TotalItems, post.Replies.TotalImgs, err = post.GetReplies() + if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollection") } - post.Replies.TotalItems = postCnt - post.Replies.TotalImgs = imgCnt - post.Attachment, err = post.Attachment[0].GetAttachment() + if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollection") } post.Preview, err = post.Preview.GetPreview() + if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollection") } result = append(result, post) } + nColl.AtContext.Context = "https://www.w3.org/ns/activitystreams" + nColl.OrderedItems = result return nColl, nil @@ -431,19 +397,22 @@ func (actor Actor) GetRecentPosts() ([]ObjectBase, error) { var collection []ObjectBase query := `select id, actor, content, published, attachment from activitystream where actor=$1 and type='Note' union select id, actor, content, published, attachment from cacheactivitystream where actor in (select follower from follower where id=$1) and type='Note' order by published desc limit 20` - rows, err := config.DB.Query(query, actor.Id) if err != nil { - log.Println("Could not get recent posts") - return collection, err + return collection, util.MakeError(err, "GetRecentPosts") } defer rows.Close() for rows.Next() { var nObj ObjectBase var attachment ObjectBase - rows.Scan(&nObj.Id, &nObj.Actor, &nObj.Content, &nObj.Published, &attachment.Id) + + err := rows.Scan(&nObj.Id, &nObj.Actor, &nObj.Content, &nObj.Published, &attachment.Id) + + if err != nil { + return collection, util.MakeError(err, "GetRecentPosts") + } isOP, _ := nObj.CheckIfOP() @@ -465,18 +434,21 @@ func (actor Actor) GetReported() ([]ObjectBase, error) { var nObj []ObjectBase query := `select id, count, reason from reported where board=$1` - rows, err := config.DB.Query(query, actor.Id) + if err != nil { - return nObj, err + return nObj, util.MakeError(err, "GetReported") } defer rows.Close() - for rows.Next() { var obj ObjectBase - rows.Scan(&obj.Id, &obj.Size, &obj.Content) + err := rows.Scan(&obj.Id, &obj.Size, &obj.Content) + + if err != nil { + return nObj, util.MakeError(err, "GetReported") + } nObj = append(nObj, obj) } @@ -489,7 +461,7 @@ func (actor Actor) GetReportedTotal() (int, error) { query := `select count(id) from reported where board=$1` if err := config.DB.QueryRow(query, actor.Id).Scan(&count); err != nil { - return 0, err + return 0, util.MakeError(err, "GetReportedTotal") } return count, nil @@ -500,18 +472,18 @@ func (actor Actor) GetAllArchive(offset int) (Collection, error) { var result []ObjectBase query := `select x.id, x.updated from (select id, updated from activitystream where actor=$1 and id in (select id from replies where inreplyto='') and type='Note' union select id, updated from activitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note' union select id, updated from cacheactivitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note') as x order by x.updated desc offset $2` - rows, err := config.DB.Query(query, actor.Id, offset) + if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetAllArchive") } - defer rows.Close() + defer rows.Close() for rows.Next() { var post ObjectBase if err := rows.Scan(&post.Id, &post.Updated); err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetAllArchive") } post.Replies, _, _, err = post.GetReplies() @@ -519,6 +491,8 @@ func (actor Actor) GetAllArchive(offset int) (Collection, error) { result = append(result, post) } + nColl.AtContext.Context = "https://www.w3.org/ns/activitystreams" + nColl.OrderedItems = result return nColl, nil @@ -526,8 +500,9 @@ func (actor Actor) GetAllArchive(offset int) (Collection, error) { func (actor Actor) IsAlreadyFollowing(follow string) (bool, error) { followers, err := actor.GetFollowing() + if err != nil { - return false, err + return false, util.MakeError(err, "IsAlreadyFollowing") } for _, e := range followers { @@ -541,8 +516,9 @@ func (actor Actor) IsAlreadyFollowing(follow string) (bool, error) { func (actor Actor) IsAlreadyFollower(follow string) (bool, error) { followers, err := actor.GetFollow() + if err != nil { - return false, err + return false, util.MakeError(err, "IsAlreadyFollower") } for _, e := range followers { @@ -556,413 +532,74 @@ func (actor Actor) IsAlreadyFollower(follow string) (bool, error) { func (actor Actor) SetActorAutoSubscribeDB() error { current, err := actor.GetAutoSubscribe() + if err != nil { - return err + return util.MakeError(err, "SetActorAutoSubscribeDB") } query := `update actor set autosubscribe=$1 where id=$2` - _, err = config.DB.Exec(query, !current, actor.Id) - return err + + return util.MakeError(err, "SetActorAutoSubscribeDB") } func (actor Actor) GetOutbox(ctx *fiber.Ctx) error { - var collection Collection c, err := actor.GetCollection() + if err != nil { - return err + return util.MakeError(err, "GetOutbox") } - collection.OrderedItems = c.OrderedItems + collection.OrderedItems = c.OrderedItems collection.AtContext.Context = "https://www.w3.org/ns/activitystreams" collection.Actor = actor - collection.TotalItems, err = GetObjectPostsTotalDB(actor) + collection.TotalItems, err = actor.GetPostTotal() + if err != nil { - return err + return util.MakeError(err, "GetOutbox") } - collection.TotalImgs, err = GetObjectImgsTotalDB(actor) + collection.TotalImgs, err = actor.GetImgTotal() + if err != nil { - return err + return util.MakeError(err, "GetOutbox") } enc, _ := json.Marshal(collection) - ctx.Response().Header.Set("Content-Type", config.ActivityStreams) _, err = ctx.Write(enc) - return err + + return util.MakeError(err, "GetOutbox") } func (actor Actor) UnArchiveLast() error { col, err := actor.GetCollectionTypeLimit("Archive", 1) + if err != nil { - return err + return util.MakeError(err, "UnArchiveLast") } for _, e := range col.OrderedItems { for _, k := range e.Replies.OrderedItems { if err := k.UpdateType("Note"); err != nil { - return err + return util.MakeError(err, "UnArchiveLast") } } if err := e.UpdateType("Note"); err != nil { - return err + return util.MakeError(err, "UnArchiveLast") } } return nil } -func GetActorByNameFromDB(name string) (Actor, error) { - var nActor Actor - var publicKeyPem string - - query := `select type, id, name, preferedusername, inbox, outbox, following, followers, restricted, summary, publickeypem from actor where name=$1` - err := config.DB.QueryRow(query, name).Scan(&nActor.Type, &nActor.Id, &nActor.Name, &nActor.PreferredUsername, &nActor.Inbox, &nActor.Outbox, &nActor.Following, &nActor.Followers, &nActor.Restricted, &nActor.Summary, &publicKeyPem) - if err != nil { - return nActor, err - } - - if nActor.Id != "" && nActor.PublicKey.PublicKeyPem == "" { - if err := CreatePublicKeyFromPrivate(&nActor, publicKeyPem); err != nil { - return nActor, err - } - } - - return nActor, nil -} - -func GetActorCollectionReq(collection string) (Collection, error) { - var nCollection Collection - - req, err := http.NewRequest("GET", collection, nil) - if err != nil { - return nCollection, err - } - - // TODO: rewrite this for fiber - pass := "FIXME" - //_, pass := GetPasswordFromSession(r) - - req.Header.Set("Accept", config.ActivityStreams) - - req.Header.Set("Authorization", "Basic "+pass) - - resp, err := util.RouteProxy(req) - if err != nil { - return nCollection, err - } - defer resp.Body.Close() - - if resp.StatusCode == 200 { - body, _ := ioutil.ReadAll(resp.Body) - - if err := json.Unmarshal(body, &nCollection); err != nil { - return nCollection, err - } - } - - return nCollection, nil -} - -func GetActorFollowNameFromPath(path string) string { - var actor string - - re := regexp.MustCompile("f\\w+-") - - actor = re.FindString(path) - - actor = strings.Replace(actor, "f", "", 1) - actor = strings.Replace(actor, "-", "", 1) - - return actor -} - -func GetActorFromDB(id string) (Actor, error) { - var nActor Actor - - query := `select type, id, name, preferedusername, inbox, outbox, following, followers, restricted, summary, publickeypem from actor where id=$1` - - var publicKeyPem string - err := config.DB.QueryRow(query, id).Scan(&nActor.Type, &nActor.Id, &nActor.Name, &nActor.PreferredUsername, &nActor.Inbox, &nActor.Outbox, &nActor.Following, &nActor.Followers, &nActor.Restricted, &nActor.Summary, &publicKeyPem) - if err != nil { - return nActor, err - } - - nActor.PublicKey, err = GetActorPemFromDB(publicKeyPem) - if err != nil { - return nActor, err - } - - if nActor.Id != "" && nActor.PublicKey.PublicKeyPem == "" { - if err := CreatePublicKeyFromPrivate(&nActor, publicKeyPem); err != nil { - return nActor, err - } - } - - return nActor, nil -} - -func GetActorFromJson(actor []byte) (Actor, error) { - var generic interface{} - var nActor Actor - err := json.Unmarshal(actor, &generic) - if err != nil { - return nActor, err - } - - if generic != nil { - switch generic.(type) { - case map[string]interface{}: - err = json.Unmarshal(actor, &nActor) - break - - case string: - var str string - err = json.Unmarshal(actor, &str) - nActor.Id = str - break - } - - return nActor, err - } - - return nActor, nil -} - -func GetActorInstance(path string) (string, string) { - re := regexp.MustCompile(`([@]?([\w\d.-_]+)[@](.+))`) - atFormat := re.MatchString(path) - - if atFormat { - match := re.FindStringSubmatch(path) - if len(match) > 2 { - return match[2], match[3] - } - } - - re = regexp.MustCompile(`(https?://)(www)?([\w\d-_.:]+)(/|\s+|\r|\r\n)?$`) - mainActor := re.MatchString(path) - if mainActor { - match := re.FindStringSubmatch(path) - if len(match) > 2 { - return "main", match[3] - } - } - - re = regexp.MustCompile(`(https?://)?(www)?([\w\d-_.:]+)\/([\w\d-_.]+)(\/([\w\d-_.]+))?`) - httpFormat := re.MatchString(path) - - if httpFormat { - match := re.FindStringSubmatch(path) - if len(match) > 3 { - if match[4] == "users" { - return match[6], match[3] - } - - return match[4], match[3] - } - } - - return "", "" -} - -func GetActorsFollowPostFromId(actors []string, id string) (Collection, error) { - var collection Collection - - for _, e := range actors { - obj := ObjectBase{Id: e + "/" + id} - tempCol, err := obj.GetCollectionFromPath() - if err != nil { - return collection, err - } - - if len(tempCol.OrderedItems) > 0 { - collection = tempCol - return collection, nil - } - } - - return collection, nil -} - -func GetActorPost(ctx *fiber.Ctx, path string) error { - obj := ObjectBase{Id: config.Domain + "" + path} - collection, err := obj.GetCollectionFromPath() - if err != nil { - return err - } - - if len(collection.OrderedItems) > 0 { - enc, err := json.MarshalIndent(collection, "", "\t") - if err != nil { - return err - } - - ctx.Response().Header.Set("Content-Type", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") - _, err = ctx.Write(enc) - return err - } - - return nil -} - -func GetBoards() ([]Actor, error) { - var boards []Actor - - query := `select type, id, name, preferedusername, inbox, outbox, following, followers FROM actor` - - rows, err := config.DB.Query(query) - if err != nil { - return boards, err - } - - defer rows.Close() - for rows.Next() { - var actor = new(Actor) - - if err := rows.Scan(&actor.Type, &actor.Id, &actor.Name, &actor.PreferredUsername, &actor.Inbox, &actor.Outbox, &actor.Following, &actor.Followers); err != nil { - return boards, err - } - - boards = append(boards, *actor) - } - - return boards, nil -} - -func IsActorLocal(id string) (bool, error) { - actor, err := GetActorFromDB(id) - return actor.Id != "", err -} - -func SetActorFollowerDB(activity Activity) (Activity, error) { - var query string - alreadyFollow, err := activity.Actor.IsAlreadyFollower(activity.Object.Actor) - if err != nil { - return activity, err - } - - activity.Type = "Reject" - if activity.Actor.Id == activity.Object.Actor { - return activity, nil - } - - if alreadyFollow { - query = `delete from follower where id=$1 and follower=$2` - activity.Summary = activity.Object.Actor + " Unfollow " + activity.Actor.Id - - if _, err := config.DB.Exec(query, activity.Actor.Id, activity.Object.Actor); err != nil { - return activity, err - } - - activity.Type = "Accept" - return activity, err - } - - query = `insert into follower (id, follower) values ($1, $2)` - activity.Summary = activity.Object.Actor + " Follow " + activity.Actor.Id - - if _, err := config.DB.Exec(query, activity.Actor.Id, activity.Object.Actor); err != nil { - return activity, err - } - - activity.Type = "Accept" - return activity, nil -} - -func (obj ObjectBase) WriteActorObjectReplyToDB() error { - for _, e := range obj.InReplyTo { - query := `select id from replies where id=$1 and inreplyto=$2` - - rows, err := config.DB.Query(query, obj.Id, e.Id) - if err != nil { - return err - } - - defer rows.Close() - - var id string - rows.Next() - rows.Scan(&id) - - if id == "" { - query := `insert into replies (id, inreplyto) values ($1, $2)` - - if _, err := config.DB.Exec(query, obj.Id, e.Id); err != nil { - return err - } - } - } - - if len(obj.InReplyTo) < 1 { - query := `select id from replies where id=$1 and inreplyto=$2` - - rows, err := config.DB.Query(query, obj.Id, "") - if err != nil { - return err - } - defer rows.Close() - - var id string - rows.Next() - rows.Scan(&id) - - if id == "" { - query := `insert into replies (id, inreplyto) values ($1, $2)` - - if _, err := config.DB.Exec(query, obj.Id, ""); err != nil { - return err - } - } - } - - return nil -} - -func (obj ObjectBase) WriteActorObjectToCache() (ObjectBase, error) { - if res, err := util.IsPostBlacklist(obj.Content); err == nil && res { - fmt.Println("\n\nBlacklist post blocked\n\n") - return obj, nil - } else if err != nil { - return obj, err - } - - if len(obj.Attachment) > 0 { - if res, err := obj.IsLocal(); err == nil && res { - return obj, err - } else if err != nil { - return obj, err - } - - if obj.Preview.Href != "" { - obj.Preview.WritePreviewCache() - } - - for i, _ := range obj.Attachment { - obj.Attachment[i].WriteAttachmentCache() - obj.WriteCacheWithAttachment(obj.Attachment[i]) - } - - } else { - if err := obj.WriteCache(); err != nil { - return obj, err - } - } - - obj.WriteActorObjectReplyToDB() - - if obj.Replies.OrderedItems != nil { - for _, e := range obj.Replies.OrderedItems { - e.WriteActorObjectToCache() - } - } - - return obj, nil +func (actor Actor) IsLocal() (bool, error) { + actor, err := GetActorFromDB(actor.Id) + return actor.Id != "", util.MakeError(err, "IsLocal") } func (actor Actor) GetCatalogCollection() (Collection, error) { @@ -973,9 +610,8 @@ func (actor Actor) GetCatalogCollection() (Collection, error) { var rows *sql.Rows query := `select x.id, x.name, x.content, x.type, x.published, x.updated, x.attributedto, x.attachment, x.preview, x.actor, x.tripcode, x.sensitive from (select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor=$1 and id in (select id from replies where inreplyto='') and type='Note' union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note' union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from cacheactivitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note') as x order by x.updated desc limit 165` - if rows, err = config.DB.Query(query, actor.Id); err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCatalogCollection") } defer rows.Close() @@ -992,7 +628,7 @@ func (actor Actor) GetCatalogCollection() (Collection, error) { err = rows.Scan(&post.Id, &post.Name, &post.Content, &post.Type, &post.Published, &post.Updated, &post.AttributedTo, &post.Attachment[0].Id, &post.Preview.Id, &actor.Id, &post.TripCode, &post.Sensitive) if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCatalogCollection") } post.Actor = actor.Id @@ -1001,11 +637,23 @@ func (actor Actor) GetCatalogCollection() (Collection, error) { post.Replies = replies - post.Replies.TotalItems, post.Replies.TotalImgs, _ = post.GetRepliesCount() + post.Replies.TotalItems, post.Replies.TotalImgs, err = post.GetRepliesCount() + + if err != nil { + return nColl, util.MakeError(err, "GetCatalogCollection") + } + + post.Attachment, err = post.Attachment[0].GetAttachment() - post.Attachment, _ = post.Attachment[0].GetAttachment() + if err != nil { + return nColl, util.MakeError(err, "GetCatalogCollection") + } - post.Preview, _ = post.Preview.GetPreview() + post.Preview, err = post.Preview.GetPreview() + + if err != nil { + return nColl, util.MakeError(err, "GetCatalogCollection") + } result = append(result, post) } @@ -1027,7 +675,7 @@ func (actor Actor) GetCollectionPage(page int) (Collection, error) { query := `select count (x.id) over(), x.id, x.name, x.content, x.type, x.published, x.updated, x.attributedto, x.attachment, x.preview, x.actor, x.tripcode, x.sensitive from (select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor=$1 and id in (select id from replies where inreplyto='') and type='Note' union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from activitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note' union select id, name, content, type, published, updated, attributedto, attachment, preview, actor, tripcode, sensitive from cacheactivitystream where actor in (select following from following where id=$1) and id in (select id from replies where inreplyto='') and type='Note') as x order by x.updated desc limit 15 offset $2` if rows, err = config.DB.Query(query, actor.Id, page*15); err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionPage") } var count int @@ -1045,22 +693,28 @@ func (actor Actor) GetCollectionPage(page int) (Collection, error) { err = rows.Scan(&count, &post.Id, &post.Name, &post.Content, &post.Type, &post.Published, &post.Updated, &post.AttributedTo, &post.Attachment[0].Id, &post.Preview.Id, &actor.Id, &post.TripCode, &post.Sensitive) if err != nil { - return nColl, err + return nColl, util.MakeError(err, "GetCollectionPage") } post.Actor = actor.Id - var postCnt int - var imgCnt int + post.Replies, post.Replies.TotalItems, post.Replies.TotalImgs, err = post.GetRepliesLimit(5) + + if err != nil { + return nColl, util.MakeError(err, "GetCollectionPage") + } - post.Replies, postCnt, imgCnt, _ = post.GetRepliesLimit(5) + post.Attachment, err = post.Attachment[0].GetAttachment() - post.Replies.TotalItems = postCnt - post.Replies.TotalImgs = imgCnt + if err != nil { + return nColl, util.MakeError(err, "GetCollectionPage") + } - post.Attachment, _ = post.Attachment[0].GetAttachment() + post.Preview, err = post.Preview.GetPreview() - post.Preview, _ = post.Preview.GetPreview() + if err != nil { + return nColl, util.MakeError(err, "GetCollectionPage") + } result = append(result, post) } @@ -1073,3 +727,42 @@ func (actor Actor) GetCollectionPage(page int) (Collection, error) { return nColl, nil } + +func (actor Actor) WantToServePage(page int) (Collection, error) { + var collection Collection + var err error + + if page > config.PostCountPerPage { + return collection, errors.New("above page limit") + } + + if collection, err = actor.GetCollectionPage(page); err != nil { + return collection, util.MakeError(err, "WantToServePage") + } + + collection.Actor = actor + + return collection, nil +} + +func (actor Actor) GetImgTotal() (int, error) { + var count int + + query := `select count(attachment) from activitystream where actor=$1 and id in (select id from replies where inreplyto='' and type='Note' )` + if err := config.DB.QueryRow(query, actor.Id).Scan(&count); err != nil { + return count, util.MakeError(err, "GetImgTotal") + } + + return count, nil +} + +func (actor Actor) GetPostTotal() (int, error) { + var count int + + query := `select count(id) from activitystream where actor=$1 and id in (select id from replies where inreplyto='' and type='Note')` + if err := config.DB.QueryRow(query, actor.Id).Scan(&count); err != nil { + return count, util.MakeError(err, "GetPostTotal") + } + + return count, nil +} -- cgit v1.2.3