<commit_before>package models

import (
	"errors"
	"github.com/koding/bongo"
	"time"
)

var (
	NOTIFIER_LIMIT = 3
)

type Notifiable interface {
	// users that will be notified are fetched while creating notification
	GetNotifiedUsers(notificationContentId int64) ([]int64, error)
	GetType() string
	GetTargetId() int64
	FetchActors() (*ActorContainer, error)
	SetTargetId(int64)
	SetListerId(int64)
}

type InteractionNotification struct {
	TargetId     int64
	TypeConstant string
	ListerId     int64
	NotifierId   int64
}

func (n *InteractionNotification) GetNotifiedUsers(notificationContentId int64) ([]int64, error) {
	i := NewInteraction()
	i.MessageId = n.TargetId

	// fetch message owner
	targetMessage := NewChannelMessage()
	if err := targetMessage.ById(n.TargetId); err != nil {
		return nil, err
	}

	notifiedUsers := make([]int64, 0)
	// notify just the owner
	if targetMessage.AccountId != n.NotifierId {
		notifiedUsers = append(notifiedUsers, targetMessage.AccountId)
	}

	return notifiedUsers, nil
}

func (n *InteractionNotification) GetType() string {
	return n.TypeConstant
}

func (n *InteractionNotification) GetTargetId() int64 {
	return n.TargetId
}

func (n *InteractionNotification) SetTargetId(targetId int64) {
	n.TargetId = targetId
}

func (n *InteractionNotification) FetchActors() (*ActorContainer, error) {
	if n.TargetId == 0 {
		return nil, errors.New("TargetId is not set")
	}

	i := NewInteraction()
	p := bongo.NewPagination(NOTIFIER_LIMIT, 0)
	i.MessageId = n.TargetId

	actors, err := i.FetchInteractorIds(n.GetType(), p)
	if err != nil {
		return nil, err
	}

	ac := NewActorContainer()
	ac.LatestActors = actors
	ac.Count, err = i.FetchInteractorCount()
	if err != nil {
		return nil, err
	}

	return ac, nil
}

func (n *InteractionNotification) SetListerId(listerId int64) {
	n.ListerId = listerId
}

func NewInteractionNotification(notificationType string) *InteractionNotification {
	return &InteractionNotification{TypeConstant: notificationType}
}

type ReplyNotification struct {
	TargetId   int64
	ListerId   int64
	NotifierId int64
}

func (n *ReplyNotification) GetNotifiedUsers(notificationContentId int64) ([]int64, error) {
	// fetch all repliers
	cm := NewChannelMessage()
	cm.Id = n.TargetId

	p := &bongo.Pagination{}
	replierIds, err := cm.FetchReplierIds(p, true, time.Time{})

	if err != nil {
		return nil, err
	}

	// regress notifier from notified users
	filteredRepliers := make([]int64, 0)
	for _, replierId := range replierIds {
		if replierId != n.NotifierId {
			filteredRepliers = append(filteredRepliers, replierId)
		}
	}

	return filteredRepliers, nil
}

func (n *ReplyNotification) GetType() string {
	return NotificationContent_TYPE_COMMENT
}

func (n *ReplyNotification) GetTargetId() int64 {
	return n.TargetId
}

func (n *ReplyNotification) SetTargetId(targetId int64) {
	n.TargetId = targetId
}<commit_msg>Social: GetNotifiedUser method now supports subscribed/unsubscribed users<commit_after>package models

import (
	"errors"
	"github.com/koding/bongo"
	"time"
)

var (
	NOTIFIER_LIMIT = 3
)

type Notifiable interface {
	// users that will be notified are fetched while creating notification
	GetNotifiedUsers(notificationContentId int64) ([]int64, error)
	GetType() string
	GetTargetId() int64
	FetchActors() (*ActorContainer, error)
	SetTargetId(int64)
	SetListerId(int64)
}

type InteractionNotification struct {
	TargetId     int64
	TypeConstant string
	ListerId     int64
	NotifierId   int64
}

func (n *InteractionNotification) GetNotifiedUsers(notificationContentId int64) ([]int64, error) {
	i := NewInteraction()
	i.MessageId = n.TargetId

	// fetch message owner
	targetMessage := NewChannelMessage()
	if err := targetMessage.ById(n.TargetId); err != nil {
		return nil, err
	}

	notifiedUsers := make([]int64, 0)
	// notify just the owner
	if targetMessage.AccountId != n.NotifierId {
		notifiedUsers = append(notifiedUsers, targetMessage.AccountId)
	}

	return notifiedUsers, nil
}

func (n *InteractionNotification) GetType() string {
	return n.TypeConstant
}

func (n *InteractionNotification) GetTargetId() int64 {
	return n.TargetId
}

func (n *InteractionNotification) SetTargetId(targetId int64) {
	n.TargetId = targetId
}

func (n *InteractionNotification) FetchActors() (*ActorContainer, error) {
	if n.TargetId == 0 {
		return nil, errors.New("TargetId is not set")
	}

	i := NewInteraction()
	p := bongo.NewPagination(NOTIFIER_LIMIT, 0)
	i.MessageId = n.TargetId

	actors, err := i.FetchInteractorIds(n.GetType(), p)
	if err != nil {
		return nil, err
	}

	ac := NewActorContainer()
	ac.LatestActors = actors
	ac.Count, err = i.FetchInteractorCount()
	if err != nil {
		return nil, err
	}

	return ac, nil
}

func (n *InteractionNotification) SetListerId(listerId int64) {
	n.ListerId = listerId
}

func NewInteractionNotification(notificationType string) *InteractionNotification {
	return &InteractionNotification{TypeConstant: notificationType}
}

type ReplyNotification struct {
	TargetId   int64
	ListerId   int64
	NotifierId int64
}

func (n *ReplyNotification) GetNotifiedUsers(notificationContentId int64) ([]int64, error) {
	// fetch all repliers
	cm := NewChannelMessage()
	cm.Id = n.TargetId

	p := &bongo.Pagination{}
	replierIds, err := cm.FetchReplierIds(p, true, time.Time{})
	if err != nil {
		return nil, err
	}
	repliersMap := map[int64]struct{}{}
	for _, replierId := range replierIds {
		repliersMap[replierId] = struct{}{}
	}

	var subscribers []NotificationSubscription
	q := &bongo.Query{
		Selector: map[string]interface{}{
			"notification_content_id": notificationContentId,
		},
	}
	ns := NewNotificationSubscription()
	if err := ns.Some(&subscribers, q); err != nil {
		return nil, err
	}

	// regress unsubscribed users and append subscribed ones
	for _, subscriber := range subscribers {
		switch subscriber.TypeConstant {
		case NotificationSubscription_TYPE_SUBSCRIBE:
			repliersMap[subscriber.AccountId] = struct{}{}
		case NotificationSubscription_TYPE_UNSUBSCRIBE:
			delete(repliersMap, subscriber.AccountId)
		}
	}

	// regress notifier from notified users
	delete(repliersMap, n.NotifierId)

	filteredRepliers := make([]int64, 0)
	for replierId, _ := range repliersMap {
		filteredRepliers = append(filteredRepliers, replierId)
	}

	return filteredRepliers, nil
}

func (n *ReplyNotification) GetType() string {
	return NotificationContent_TYPE_COMMENT
}

func (n *ReplyNotification) GetTargetId() int64 {
	return n.TargetId
}

func (n *ReplyNotification) SetTargetId(targetId int64) {
	n.TargetId = targetId
}
{'fraction_non_alphanumeric': 0.10588953310955142, 'fraction_numerical': 0.015257857796765334, 'mean_word_length': 4.9107303877367, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2961542', 'n_tokens_mistral': 2298, 'n_tokens_neox': 2186, 'n_words': 548}