334 строки
9.3 KiB
Ruby
334 строки
9.3 KiB
Ruby
require 'rubygems'
|
|
require 'bundler'
|
|
|
|
Bundler.setup
|
|
Bundler.require
|
|
|
|
require 'tire/queries/more_like_this'
|
|
|
|
env_index = ARGV.index("-e")
|
|
env_arg = ARGV[env_index + 1] if env_index
|
|
environment = env_arg || ENV["SINATRA_ENV"] || "development"
|
|
RACK_ENV = environment
|
|
|
|
module CommentService
|
|
class << self; attr_accessor :config; end
|
|
API_VERSION = 'v1'
|
|
API_PREFIX = "/api/#{API_VERSION}"
|
|
end
|
|
|
|
CommentService.config = YAML.load_file("config/application.yml")
|
|
|
|
Mongoid.load!("config/mongoid.yml", environment)
|
|
Mongoid.logger.level = Logger::INFO
|
|
|
|
Dir[File.dirname(__FILE__) + '/lib/**/*.rb'].each {|file| require file}
|
|
Dir[File.dirname(__FILE__) + '/models/*.rb'].each {|file| require file}
|
|
Dir[File.dirname(__FILE__) + '/models/observers/*.rb'].each {|file| require file}
|
|
|
|
Mongoid.observers = PostReplyObserver, PostTopicObserver, AtUserObserver
|
|
Mongoid.instantiate_observers
|
|
|
|
api_prefix = CommentService::API_PREFIX
|
|
|
|
|
|
get "#{api_prefix}/search/threads" do
|
|
|
|
sort_key_mapper = {
|
|
"date" => :created_at,
|
|
"activity" => :last_activity_at,
|
|
"votes" => :votes_point,
|
|
"comments" => :comment_count,
|
|
}
|
|
|
|
sort_order_mapper = {
|
|
"desc" => :desc,
|
|
"asc" => :asc,
|
|
}
|
|
|
|
sort_key = sort_key_mapper[params["sort_key"]]
|
|
sort_order = sort_order_mapper[params["sort_order"]]
|
|
|
|
sort_keyword_valid = (!params["sort_key"] && !params["sort_order"] || sort_key && sort_order)
|
|
|
|
if (!params["text"] && !params["tags"]) || !sort_keyword_valid
|
|
{}.to_json
|
|
else
|
|
page = (params["page"] || 1).to_i
|
|
per_page = (params["per_page"] || 20).to_i
|
|
|
|
options = {
|
|
sort_key: sort_key,
|
|
sort_order: sort_order,
|
|
page: page,
|
|
per_page: per_page,
|
|
}
|
|
|
|
results = CommentThread.perform_search(params, options).results
|
|
|
|
if page > results.total_pages #TODO find a better way for this
|
|
results = CommentThread.perform_search(params, options.merge(page: results.total_pages)).results
|
|
end
|
|
|
|
num_pages = results.total_pages
|
|
page = [num_pages, [1, page].max].min
|
|
{
|
|
collection: results.map{|t| CommentThread.search_result_to_hash(t, recursive: bool_recursive)},
|
|
num_pages: num_pages,
|
|
page: page,
|
|
}.to_json
|
|
end
|
|
end
|
|
|
|
get "#{api_prefix}/search/threads/more_like_this" do
|
|
CommentThread.tire.search page: 1, per_page: 5, load: true do |search|
|
|
search.query do |query|
|
|
query.more_like_this params["text"], fields: ["title", "body"], min_doc_freq: 1, min_term_freq: 1
|
|
end
|
|
end.results.map(&:to_hash).to_json
|
|
end
|
|
|
|
get "#{api_prefix}/search/threads/recent_active" do
|
|
|
|
return [].to_json if not params["course_id"]
|
|
|
|
follower_id = params["follower_id"]
|
|
from_time = {
|
|
"today" => Date.today.to_time,
|
|
"this_week" => Date.today.to_time - 1.weeks,
|
|
"this_month" => Date.today.to_time - 1.months,
|
|
}[params["from_time"] || "today"]
|
|
|
|
query_params = {}
|
|
query_params["course_id"] = params["course_id"] if params["course_id"]
|
|
query_params["commentable_id"] = params["commentable_id"] if params["commentable_id"]
|
|
|
|
comment_threads = if follower_id
|
|
User.find(follower_id).subscribed_threads.select do |thread|
|
|
thread.last_activity_at >= from_time and \
|
|
query_params.to_a.map {|query| thread[query.first] == query.last}.all?
|
|
end
|
|
else
|
|
CommentThread.all.where(query_params.merge(:last_activity_at => {:$gte => from_time}))
|
|
end
|
|
|
|
comment_threads.to_a.sort {|x, y| y.last_activity_at <=> x.last_activity_at}[0..4].to_json
|
|
end
|
|
|
|
#
|
|
#get "#{api_prefix}/search/tags/trending" do
|
|
# query_params = {}
|
|
# query_params["course_id"] = params["course_id"] if params["course_id"]
|
|
# query_params["commentable_id"] = params["commentable_id"] if params["commentable_id"]
|
|
# CommentThread.all.where(query_params).to_a.map(&:tags_array).flatten.g
|
|
#end
|
|
|
|
delete "#{api_prefix}/:commentable_id/threads" do |commentable_id|
|
|
commentable.comment_threads.destroy_all
|
|
{}.to_json
|
|
end
|
|
|
|
get "#{api_prefix}/:commentable_id/threads" do |commentable_id|
|
|
|
|
sort_key_mapper = {
|
|
"date" => :created_at,
|
|
"activity" => :last_activity_at,
|
|
"votes" => :"votes.point",
|
|
"comments" => :comment_count,
|
|
}
|
|
|
|
sort_order_mapper = {
|
|
"desc" => :desc,
|
|
"asc" => :asc,
|
|
}
|
|
|
|
sort_key = sort_key_mapper[params["sort_key"]]
|
|
sort_order = sort_order_mapper[params["sort_order"]]
|
|
sort_keyword_valid = (!params["sort_key"] && !params["sort_order"] || sort_key && sort_order)
|
|
if not sort_keyword_valid
|
|
{}.to_json
|
|
else
|
|
page = (params["page"] || 1).to_i
|
|
per_page = (params["per_page"] || 20).to_i
|
|
comment_threads = commentable.comment_threads
|
|
comment_threads = comment_threads.order_by("#{sort_key} #{sort_order}") if sort_key && sort_order
|
|
num_pages = [1, (comment_threads.count / per_page.to_f).ceil].max
|
|
page = [num_pages, [1, page].max].min
|
|
paged_comment_threads = comment_threads.page(page).per(per_page)
|
|
{
|
|
collection: paged_comment_threads.map{|t| t.to_hash(recursive: bool_recursive)},
|
|
num_pages: num_pages,
|
|
page: page,
|
|
}.to_json
|
|
end
|
|
end
|
|
|
|
post "#{api_prefix}/:commentable_id/threads" do |commentable_id|
|
|
thread = CommentThread.new(params.slice(*%w[title body course_id]).merge(commentable_id: commentable_id))
|
|
thread.anonymous = bool_anonymous || false
|
|
thread.tags = params["tags"] || ""
|
|
thread.author = user
|
|
thread.save
|
|
if thread.errors.any?
|
|
error 400, thread.errors.full_messages.to_json
|
|
else
|
|
user.subscribe(thread) if bool_auto_subscribe
|
|
thread.to_hash.to_json
|
|
end
|
|
end
|
|
|
|
get "#{api_prefix}/threads/tags" do
|
|
CommentThread.tags.to_json
|
|
end
|
|
|
|
get "#{api_prefix}/threads/tags/autocomplete" do
|
|
CommentThread.tags_autocomplete(params["value"].strip, max: 5, sort_by_count: true).map(&:first).to_json
|
|
end
|
|
|
|
get "#{api_prefix}/threads/:thread_id" do |thread_id|
|
|
CommentThread.find(thread_id).to_hash(recursive: bool_recursive).to_json
|
|
end
|
|
|
|
put "#{api_prefix}/threads/:thread_id" do |thread_id|
|
|
thread.update_attributes(params.slice(*%w[title body closed]))
|
|
if params["tags"]
|
|
thread.tags = params["tags"]
|
|
thread.save
|
|
end
|
|
if thread.errors.any?
|
|
error 400, thread.errors.full_messages.to_json
|
|
else
|
|
thread.to_hash.to_json
|
|
end
|
|
end
|
|
|
|
post "#{api_prefix}/threads/:thread_id/comments" do |thread_id|
|
|
comment = thread.comments.new(params.slice(*%w[body course_id]))
|
|
comment.anonymous = bool_anonymous || false
|
|
comment.author = user
|
|
comment.save
|
|
if comment.errors.any?
|
|
error 400, comment.errors.full_messages.to_json
|
|
else
|
|
user.subscribe(thread) if bool_auto_subscribe
|
|
comment.to_hash.to_json
|
|
end
|
|
end
|
|
|
|
delete "#{api_prefix}/threads/:thread_id" do |thread_id|
|
|
thread.destroy
|
|
thread.to_hash.to_json
|
|
end
|
|
|
|
get "#{api_prefix}/comments/:comment_id" do |comment_id|
|
|
comment.to_hash(recursive: bool_recursive).to_json
|
|
end
|
|
|
|
put "#{api_prefix}/comments/:comment_id" do |comment_id|
|
|
comment.update_attributes(params.slice(*%w[body endorsed]))
|
|
if comment.errors.any?
|
|
error 400, comment.errors.full_messages.to_json
|
|
else
|
|
comment.to_hash.to_json
|
|
end
|
|
end
|
|
|
|
post "#{api_prefix}/comments/:comment_id" do |comment_id|
|
|
sub_comment = comment.children.new(params.slice(*%w[body course_id]))
|
|
sub_comment.anonymous = bool_anonymous || false
|
|
sub_comment.author = user
|
|
sub_comment.comment_thread = comment.comment_thread
|
|
sub_comment.save
|
|
if sub_comment.errors.any?
|
|
error 400, sub_comment.errors.full_messages.to_json
|
|
else
|
|
user.subscribe(comment.comment_thread) if bool_auto_subscribe
|
|
sub_comment.to_hash.to_json
|
|
end
|
|
end
|
|
|
|
delete "#{api_prefix}/comments/:comment_id" do |comment_id|
|
|
comment.destroy
|
|
comment.to_hash.to_json
|
|
end
|
|
|
|
put "#{api_prefix}/comments/:comment_id/votes" do |comment_id|
|
|
vote_for comment
|
|
end
|
|
|
|
delete "#{api_prefix}/comments/:comment_id/votes" do |comment_id|
|
|
undo_vote_for comment
|
|
end
|
|
|
|
put "#{api_prefix}/threads/:thread_id/votes" do |thread_id|
|
|
vote_for thread
|
|
end
|
|
|
|
delete "#{api_prefix}/threads/:thread_id/votes" do |thread_id|
|
|
undo_vote_for thread
|
|
end
|
|
|
|
post "#{api_prefix}/users" do
|
|
user = User.new(external_id: params["id"])
|
|
user.username = params["username"]
|
|
user.email = params["email"]
|
|
user.save
|
|
if user.errors.any?
|
|
error 400, user.errors.full_messages.to_json
|
|
else
|
|
user.to_hash.to_json
|
|
end
|
|
end
|
|
|
|
get "#{api_prefix}/users/:user_id" do |user_id|
|
|
user.to_hash(complete: bool_complete).to_json
|
|
end
|
|
|
|
put "#{api_prefix}/users/:user_id" do |user_id|
|
|
user = User.where(external_id: user_id).first
|
|
if not user
|
|
user = User.new(external_id: user_id)
|
|
end
|
|
user.update_attributes(params.slice(*%w[username email]))
|
|
if user.errors.any?
|
|
error 400, user.errors.full_messages.to_json
|
|
else
|
|
user.to_hash.to_json
|
|
end
|
|
end
|
|
|
|
get "#{api_prefix}/users/:user_id/notifications" do |user_id|
|
|
user.notifications.map(&:to_hash).to_json
|
|
end
|
|
|
|
post "#{api_prefix}/users/:user_id/subscriptions" do |user_id|
|
|
user.subscribe(source).to_hash.to_json
|
|
end
|
|
|
|
delete "#{api_prefix}/users/:user_id/subscriptions" do |user_id|
|
|
user.unsubscribe(source).to_hash.to_json
|
|
end
|
|
|
|
if environment.to_s == "development"
|
|
get "#{api_prefix}/clean" do
|
|
Comment.delete_all
|
|
CommentThread.delete_all
|
|
User.delete_all
|
|
Notification.delete_all
|
|
Subscription.delete_all
|
|
{}.to_json
|
|
end
|
|
end
|
|
|
|
error Moped::Errors::InvalidObjectId do
|
|
error 400, ["requested object not found"].to_json
|
|
end
|
|
|
|
error Mongoid::Errors::DocumentNotFound do
|
|
error 400, ["requested object not found"].to_json
|
|
end
|
|
|
|
error ArgumentError do
|
|
error 400, [env['sinatra.error'].message].to_json
|
|
end
|