Пример #1
0
func generateMessageListQuery(q *request.Query) *bongo.Query {
	messageType := q.Type
	if messageType == "" {
		messageType = ChannelMessage_TYPE_POST
	}

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"type_constant": messageType,
		},
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
	}

	if q.GroupChannelId != 0 {
		query.Selector["initial_channel_id"] = q.GroupChannelId
	}

	if q.AccountId != 0 {
		query.Selector["account_id"] = q.AccountId
	}

	query.AddScope(ExcludeFields(q.Exclude))
	query.AddScope(StartFrom(q.From))
	query.AddScope(TillTo(q.To))

	return query
}
Пример #2
0
// FetchMessageIds fetch id of the messages in the channel
// sorts the messages by descending order
func (c *ChannelMessage) FetchMessageIds(q *request.Query) ([]int64, error) {
	query := &bongo.Query{
		Selector: map[string]interface{}{
			"account_id":    q.AccountId,
			"type_constant": q.Type,
		},
		Pluck:      "id",
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
		Sort: map[string]string{
			"created_at": "DESC",
		},
	}

	query.AddScope(RemoveTrollContent(c, q.ShowExempt))

	var messageIds []int64
	if err := c.Some(&messageIds, query); err != nil {
		return nil, err
	}

	if messageIds == nil {
		return make([]int64, 0), nil
	}

	return messageIds, nil
}
Пример #3
0
func (c *Channel) FetchLastMessageId() (int64, error) {
	if c.Id == 0 {
		return 0, ErrChannelIdIsNotSet
	}

	cml := NewChannelMessageList()
	query := &bongo.Query{
		Selector: map[string]interface{}{
			"channel_id": c.Id,
		},
		Sort: map[string]string{
			"added_at": "DESC",
		},
		Pagination: *bongo.NewPagination(1, 0),
		Pluck:      "message_id",
	}

	var messageIds []int64
	err := cml.Some(&messageIds, query)
	if err != nil {
		return 0, err
	}

	if messageIds == nil || len(messageIds) == 0 {
		return 0, bongo.RecordNotFound
	}

	return messageIds[0], nil
}
Пример #4
0
func getMessageByUrl(u *url.URL) (*models.ChannelMessage, error) {

	// TODO
	// fmt.Println(`
	// 	------->
	//             ADD SECURTY CHECK FOR VISIBILTY OF THE MESSAGE
	//                         FOR THE REQUESTER
	//     ------->"`,
	// )

	id, err := request.GetURIInt64(u, "id")
	if err != nil {
		return nil, err
	}

	// get url query params
	q := request.GetQuery(u)

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"id": id,
		},
		Pagination: *bongo.NewPagination(1, 0),
	}

	cm := models.NewChannelMessage()
	// add exempt info
	query.AddScope(models.RemoveTrollContent(cm, q.ShowExempt))

	if err := cm.One(query); err != nil {
		return nil, err
	}

	return cm, nil
}
Пример #5
0
func (c *ChannelParticipant) ListAccountIds(limit int) ([]int64, error) {
	var participants []int64

	if c.ChannelId == 0 {
		return participants, ErrChannelIdIsNotSet
	}

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"channel_id":      c.ChannelId,
			"status_constant": ChannelParticipant_STATUS_ACTIVE,
		},
		Pluck: "account_id",
	}

	if limit != 0 {
		query.Pagination = *bongo.NewPagination(limit, 0)
	}

	// do not include troll content
	query.AddScope(RemoveTrollContent(c, false))

	err := bongo.B.Some(c, &participants, query)
	if err != nil {
		return nil, err
	}

	return participants, nil
}
Пример #6
0
// FetchMessageIdsByChannelId fetchs the channels by message id
func (c *ChannelMessageList) FetchMessageIdsByChannelId(channelId int64, q *request.Query) ([]int64, error) {
	query := &bongo.Query{
		Selector: map[string]interface{}{
			"channel_id": channelId,
		},
		Pluck:      "message_id",
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
		Sort: map[string]string{
			"added_at": "DESC",
		},
	}

	// remove troll content
	query.AddScope(RemoveTrollContent(c, q.ShowExempt))

	var messageIds []int64
	if err := c.Some(&messageIds, query); err != nil {
		return nil, err
	}

	if messageIds == nil {
		return make([]int64, 0), nil
	}

	return messageIds, nil
}
Пример #7
0
func (c *Channel) List(q *request.Query) ([]Channel, error) {
	if q.GroupName == "" {
		return nil, ErrGroupNameIsNotSet
	}

	var channels []Channel

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"group_name": q.GroupName,
		},
		Sort: map[string]string{
			"created_at": "DESC",
		},
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
	}

	if q.Type != "" {
		query.Selector["type_constant"] = q.Type
	}

	query.AddScope(RemoveTrollContent(c, q.ShowExempt))

	err := c.Some(&channels, query)
	if err != nil {
		return nil, err
	}

	if channels == nil {
		return make([]Channel, 0), nil
	}

	return channels, nil
}
Пример #8
0
// ByName fetches the channel by name, type_constant and group_name, it doesnt
// have the best name, but evolved to this situation :/
func (c *Channel) ByName(q *request.Query) (Channel, error) {
	var channel Channel

	if q.GroupName == "" {
		return channel, ErrGroupNameIsNotSet
	}

	if q.Type == "" {
		q.Type = Channel_TYPE_TOPIC
	}

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"group_name":    q.GroupName,
			"type_constant": q.Type,
			"name":          q.Name,
		},
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
	}

	query.AddScope(RemoveTrollContent(c, q.ShowExempt))

	err := c.One(query)
	if err != nil && err != bongo.RecordNotFound {
		return channel, err
	}

	return *c, nil
}
Пример #9
0
// FetchChannelIdByNameAndGroupName fetchs the first ID of the channel via channel name & group name
//
// Tests are done..
func (c *Channel) FetchChannelIdByNameAndGroupName(name, groupName string) (int64, error) {
	if name == "" {
		return 0, ErrNameIsNotSet
	}

	if groupName == "" {
		return 0, ErrGroupNameIsNotSet
	}

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"name":       name,
			"group_name": groupName,
		},
		Pagination: *bongo.NewPagination(1, 0),
		Pluck:      "id",
	}
	var ids []int64
	if err := c.Some(&ids, query); err != nil {
		return 0, err
	}

	if ids == nil {
		return 0, bongo.RecordNotFound
	}

	if len(ids) == 0 {
		return 0, bongo.RecordNotFound
	}

	return ids[0], nil
}
Пример #10
0
// FetchAccountsWithBongoOffset fetches the accounts with bongo
func FetchAccountsWithBongoOffset(limit, offset int) ([]Account, error) {
	acc := &Account{}
	var accounts []Account
	query := &bongo.Query{
		Pagination: *bongo.NewPagination(limit, offset),
	}
	if err := acc.Some(&accounts, query); err != nil {
		return nil, err
	}

	return accounts, nil
}
Пример #11
0
func main() {
	r := runner.New(Name)
	if err := r.Init(); err != nil {
		fmt.Println(err)
		return
	}
	defer r.Close()

	// init mongo connection
	appConfig := config.MustRead(r.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	algolia := algoliasearch.NewClient(
		appConfig.Algolia.AppId,
		appConfig.Algolia.ApiSecretKey,
	)

	// create message handler
	handler := algoliaconnector.New(r.Log, algolia, appConfig.Algolia.IndexSuffix)
	counter := 0
	for b := 0; ; b++ {
		var accounts []models.Account

		err := (&models.Account{}).Some(&accounts, &bongo.Query{
			Pagination: *bongo.NewPagination(100, b*100),
		})
		if err != nil {
			r.Log.Error(err.Error())
			continue
		}

		for _, account := range accounts {
			counter++
			r.Log.Info("[%d]: currently migrating: '%v'", counter, account.Nick)
			if err := handler.AccountUpdated(&account); err != nil {
				r.Log.Error(err.Error())
				continue
			}
		}

		if len(accounts) < 100 {
			break
		}
	}
}
Пример #12
0
func (c *ChannelMessageList) getMessages(q *request.Query) ([]*ChannelMessageContainer, error) {
	if c.ChannelId == 0 {
		return nil, ErrChannelIdIsNotSet
	}

	query := &bongo.Query{
		Selector: map[string]interface{}{
			"channel_id": c.ChannelId,
		},
		Pluck:      "message_id",
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
	}

	query.AddScope(RemoveTrollContent(c, q.ShowExempt))
	if q.SortOrder == "ASC" {
		query.AddScope(SortedByAddedAtASC)
	} else {
		query.AddScope(SortedByAddedAt)
	}

	bongoQuery := bongo.B.BuildQuery(c, query)

	if !q.From.IsZero() {
		if q.SortOrder == "ASC" {
			bongoQuery = bongoQuery.Where("added_at > ?", q.From)
		} else {
			bongoQuery = bongoQuery.Where("added_at < ?", q.From)
		}
	}

	var messages []int64
	if err := bongo.CheckErr(
		bongoQuery.Pluck(query.Pluck, &messages),
	); err != nil {
		return nil, err
	}

	populatedChannelMessages, err := c.PopulateChannelMessages(messages, q)
	if err != nil {
		return nil, err
	}

	return populatedChannelMessages, nil
}
Пример #13
0
func (c *Channel) Search(q *request.Query) ([]Channel, error) {
	if q.GroupName == "" {
		return nil, ErrGroupNameIsNotSet
	}

	if q.Type == "" {
		q.Type = Channel_TYPE_TOPIC
	}

	var channels []Channel

	bongoQuery := &bongo.Query{
		Selector: map[string]interface{}{
			"group_name":    q.GroupName,
			"type_constant": q.Type,
		},
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
	}

	bongoQuery.AddScope(RemoveTrollContent(c, q.ShowExempt))

	query := bongo.B.BuildQuery(c, bongoQuery)

	// use 'ilike' for case-insensitive search
	query = query.Where("name ilike ?", "%"+q.Name+"%")

	if err := bongo.CheckErr(
		query.Find(&channels),
	); err != nil {
		return nil, err
	}

	if channels == nil {
		return make([]Channel, 0), nil
	}

	return channels, nil
}
Пример #14
0
func FetchMessageIdsByChannelId(channelId int64, q *request.Query) ([]int64, error) {
	query := &bongo.Query{
		Selector: map[string]interface{}{
			"channel_id": channelId,
		},
		Pluck:      "message_id",
		Pagination: *bongo.NewPagination(q.Limit, q.Skip),
		Sort: map[string]string{
			"added_at": "DESC",
		},
	}

	var messageIds []int64
	if err := models.NewChannelMessageList().Some(&messageIds, query); err != nil {
		return nil, err
	}

	if messageIds == nil {
		return make([]int64, 0), nil
	}

	return messageIds, nil
}
Пример #15
0
func (m *MessageReply) fetchMessages(query *request.Query) ([]ChannelMessage, error) {
	if m.MessageId == 0 {
		return nil, ErrMessageIdIsNotSet
	}

	q := &bongo.Query{
		Selector: map[string]interface{}{
			"message_id": m.MessageId,
		},
		Pluck:      "reply_id",
		Pagination: *bongo.NewPagination(query.Limit, query.Skip),
		Sort:       map[string]string{"created_at": "DESC"},
	}

	q.AddScope(RemoveTrollContent(m, query.ShowExempt))

	bongoQuery := bongo.B.BuildQuery(m, q)
	if !query.From.IsZero() {
		bongoQuery = bongoQuery.Where("created_at < ?", query.From)
	}

	var replies []int64
	if err := bongo.CheckErr(
		bongoQuery.Pluck(q.Pluck, &replies),
	); err != nil {
		return nil, err
	}

	parent := NewChannelMessage()
	channelMessageReplies, err := parent.FetchByIds(replies)
	if err != nil {
		return nil, err
	}

	return channelMessageReplies, nil
}
Пример #16
0
// this is a TEMP function just for @usirin
func TempList(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	channelId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	c, err := models.Cache.Channel.ById(channelId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// if channel is exempt and user should see the
	// content, return not found err
	if !query.ShowExempt {
		query.ShowExempt = context.Client.Account.IsTroll
	}

	if c.MetaBits.Is(models.Troll) && !query.ShowExempt {
		return response.NewNotFound()
	}

	// check if channel is accessible by the requester
	canOpen, err := c.CanOpen(query.AccountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewAccessDenied(
			fmt.Errorf(
				"account (%d) tried to retrieve the unattended private channel (%d)",
				query.AccountId,
				c.Id,
			))
	}

	bq := &bongo.Query{
		Selector: map[string]interface{}{
			"initial_channel_id": c.Id,
		},
		Pagination: *bongo.NewPagination(query.Limit, query.Skip),
		Pluck:      "id",
	}

	bq.AddScope(models.SortedByCreatedAt)
	bq.AddScope(models.RemoveTrollContent(c, query.ShowExempt))
	bq.AddScope(models.ExcludeFields(query.Exclude))
	bq.AddScope(models.TillTo(query.From))

	bqq := bongo.B.BuildQuery(models.NewChannelMessage(), bq)
	var messages []int64
	if err := bongo.CheckErr(
		bqq.Pluck(bq.Pluck, &messages),
	); err != nil {
		return response.NewBadRequest(err)
	}

	// get the messages in regarding channel
	cmcs, err := models.
		NewChannelMessageList().
		PopulateChannelMessages(
			messages, query,
		)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// reduce replies
	replyIds := make([]int64, 0)
	for i := range cmcs {
		cmc := cmcs[i]
		if cmc.Message.TypeConstant == models.ChannelMessage_TYPE_REPLY {
			replyIds = append(replyIds, cmc.Message.Id)
		}
	}

	if len(replyIds) == 0 {
		return response.NewOK(cmcs)
	}

	// select replies
	var mrs []models.MessageReply
	gerr := bongo.B.
		BuildQuery(models.NewMessageReply(), &bongo.Query{}).
		Where("reply_id in (?)", replyIds).
		Find(&mrs)

	if err := bongo.CheckErr(gerr); err != nil {
		return response.NewBadRequest(err)
	}

	// set their parent ids
	for j, mr := range mrs {
		for i := range cmcs {
			if mr.ReplyId == cmcs[i].Message.Id {
				cmcs[i].ParentID = mrs[j].MessageId
			}
		}
	}

	// send response
	return response.NewOK(cmcs)
}