handle_threads_query

in lib/helpers.rb [130:238]


  def handle_threads_query(
    comment_threads,
    user_id,
    course_id,
    group_ids,
    filter_flagged,
    filter_unread,
    filter_unanswered,
    sort_key,
    page,
    per_page,
    context=:course
  )
    context_threads = comment_threads.where({:context => context})

    if not group_ids.empty?
      group_threads = get_group_id_criteria(comment_threads, group_ids)
      comment_threads = comment_threads.all_of(context_threads.selector, group_threads.selector)
    else
      comment_threads = context_threads
    end

    if filter_flagged
      self.class.trace_execution_scoped(['Custom/handle_threads_query/find_flagged']) do
        
        comment_ids = Comment.where(:course_id => course_id).
          where(:abuse_flaggers.ne => [], :abuse_flaggers.exists => true).
          collect{|c| c.comment_thread_id}.uniq

        thread_ids = comment_threads.where(:abuse_flaggers.ne => [], :abuse_flaggers.exists => true).
          collect{|c| c.id}

        comment_threads = comment_threads.in({"_id" => (comment_ids + thread_ids).uniq})
      end
    end

    if filter_unanswered
      self.class.trace_execution_scoped(['Custom/handle_threads_query/find_unanswered']) do
        endorsed_thread_ids = Comment.where(:course_id => course_id).
          where(:parent_id.exists => false, :endorsed => true).
          collect{|c| c.comment_thread_id}.uniq

        comment_threads = comment_threads.where({"thread_type" => :question}).nin({"_id" => endorsed_thread_ids})
      end
    end

    sort_criteria = get_sort_criteria(sort_key)
    if not sort_criteria
      {}
    else
      request_user = user_id ? user : nil
      page = (page || DEFAULT_PAGE).to_i
      per_page = (per_page || DEFAULT_PER_PAGE).to_i

      comment_threads = comment_threads.order_by(sort_criteria)

      if request_user and filter_unread
        
        
        read_dates = {}
        read_state = request_user.read_states.where(:course_id => course_id).first
        if read_state
          read_dates = read_state["last_read_times"].to_hash
        end

        threads = []
        skipped = 0
        to_skip = (page - 1) * per_page
        has_more = false
        
        comment_threads.batch_size(CommentService.config["manual_pagination_batch_size"].to_i).each do |thread|
         thread_key = thread._id.to_s
          if !read_dates.has_key?(thread_key) || read_dates[thread_key] < thread.last_activity_at
            if skipped >= to_skip
              if threads.length == per_page
                has_more = true
                break
              end
              threads << thread
            else
              skipped += 1
            end
          end
        end

        
        
        
        
        
        
        num_pages = has_more ? page + 1 : page
      else
        
        num_pages = [1, (comment_threads.count / per_page.to_f).ceil].max
        page = [1, page].max
        threads = comment_threads.paginate(:page => page, :per_page => per_page).to_a
      end

      if threads.length == 0
        collection = []
      else
        pres_threads = ThreadListPresenter.new(threads, request_user, course_id)
        collection = pres_threads.to_hash
      end
      {collection: collection, num_pages: num_pages, page: page, thread_count: comment_threads.count}
    end
  end