Commit 5c5a5a6c by jimabramson Committed by jsa

deprecate unused tagging feature

parent f8fb343a
...@@ -26,7 +26,6 @@ gem 'delayed_job_mongoid', :git => 'https://github.com/dementrock/delayed_job_mo ...@@ -26,7 +26,6 @@ gem 'delayed_job_mongoid', :git => 'https://github.com/dementrock/delayed_job_mo
gem 'mongoid-tree', :git => 'https://github.com/dementrock/mongoid-tree.git' gem 'mongoid-tree', :git => 'https://github.com/dementrock/mongoid-tree.git'
gem 'voteable_mongo', :git => 'https://github.com/dementrock/voteable_mongo.git' gem 'voteable_mongo', :git => 'https://github.com/dementrock/voteable_mongo.git'
gem 'mongoid_taggable_with_context', :git => 'https://github.com/dementrock/mongoid_taggable_with_context.git'
gem 'mongoid_magic_counter_cache', :git => 'https://github.com/dementrock/mongoid-magic-counter-cache.git' gem 'mongoid_magic_counter_cache', :git => 'https://github.com/dementrock/mongoid-magic-counter-cache.git'
gem 'kaminari', :require => 'kaminari/sinatra', :git => 'https://github.com/dementrock/kaminari.git' gem 'kaminari', :require => 'kaminari/sinatra', :git => 'https://github.com/dementrock/kaminari.git'
......
...@@ -30,13 +30,6 @@ GIT ...@@ -30,13 +30,6 @@ GIT
mongoid (>= 3.0, <= 4.0) mongoid (>= 3.0, <= 4.0)
GIT GIT
remote: https://github.com/dementrock/mongoid_taggable_with_context.git
revision: 7cf165bd828f969cdd386102eed04ac35431a920
specs:
mongoid_taggable_with_context (0.8.1.1)
mongoid (>= 3.0.1)
GIT
remote: https://github.com/dementrock/voteable_mongo.git remote: https://github.com/dementrock/voteable_mongo.git
revision: 538e86856daa1c180ba80b7c6f2805e531ba420c revision: 538e86856daa1c180ba80b7c6f2805e531ba420c
specs: specs:
...@@ -184,7 +177,6 @@ DEPENDENCIES ...@@ -184,7 +177,6 @@ DEPENDENCIES
mongoid (~> 3.0) mongoid (~> 3.0)
mongoid-tree! mongoid-tree!
mongoid_magic_counter_cache! mongoid_magic_counter_cache!
mongoid_taggable_with_context!
moped (= 1.5.1) moped (= 1.5.1)
newrelic_moped newrelic_moped
newrelic_rpm newrelic_rpm
......
...@@ -25,10 +25,6 @@ end ...@@ -25,10 +25,6 @@ end
put "#{APIPREFIX}/threads/:thread_id" do |thread_id| put "#{APIPREFIX}/threads/:thread_id" do |thread_id|
thread.update_attributes(params.slice(*%w[title body closed commentable_id group_id])) thread.update_attributes(params.slice(*%w[title body closed commentable_id group_id]))
filter_blocked_content thread filter_blocked_content thread
if params["tags"]
thread.tags = params["tags"]
thread.save
end
if thread.errors.any? if thread.errors.any?
error 400, thread.errors.full_messages.to_json error 400, thread.errors.full_messages.to_json
......
...@@ -18,7 +18,6 @@ post "#{APIPREFIX}/:commentable_id/threads" do |commentable_id| ...@@ -18,7 +18,6 @@ post "#{APIPREFIX}/:commentable_id/threads" do |commentable_id|
thread = CommentThread.new(params.slice(*%w[title body course_id ]).merge(commentable_id: commentable_id)) thread = CommentThread.new(params.slice(*%w[title body course_id ]).merge(commentable_id: commentable_id))
thread.anonymous = bool_anonymous || false thread.anonymous = bool_anonymous || false
thread.anonymous_to_peers = bool_anonymous_to_peers || false thread.anonymous_to_peers = bool_anonymous_to_peers || false
thread.tags = params["tags"] || ""
if params["group_id"] if params["group_id"]
thread.group_id = params["group_id"] thread.group_id = params["group_id"]
......
...@@ -19,7 +19,7 @@ get "#{APIPREFIX}/search/threads" do ...@@ -19,7 +19,7 @@ get "#{APIPREFIX}/search/threads" do
sort_keyword_valid = (!params["sort_key"] && !params["sort_order"] || sort_key && sort_order) sort_keyword_valid = (!params["sort_key"] && !params["sort_order"] || sort_key && sort_order)
if (!params["text"] && !params["tags"] && !params["commentable_ids"]) || !sort_keyword_valid if (!params["text"] && !params["commentable_ids"]) || !sort_keyword_valid
{}.to_json {}.to_json
else else
page = (params["page"] || DEFAULT_PAGE).to_i page = (params["page"] || DEFAULT_PAGE).to_i
...@@ -95,15 +95,3 @@ get "#{APIPREFIX}/search/threads/recent_active" do ...@@ -95,15 +95,3 @@ get "#{APIPREFIX}/search/threads/recent_active" do
comment_threads.where(query_params.merge(:last_activity_at => {:$gte => from_time})).order_by(:last_activity_at.desc).limit(5).to_a.map(&:to_hash).to_json comment_threads.where(query_params.merge(:last_activity_at => {:$gte => from_time})).order_by(:last_activity_at.desc).limit(5).to_a.map(&:to_hash).to_json
end end
get "#{APIPREFIX}/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.where(query_params).only(:tags_array).to_a
.map(&:tags_array).flatten.group_by{|x| x}
.map{|k, v| [k, v.count]}
.sort_by {|x| - x.last}[0..4]
.to_json
end
get "#{APIPREFIX}/threads/tags" do
CommentThread.tags.to_json
end
get "#{APIPREFIX}/threads/tags/autocomplete" do
CommentThread.tags_autocomplete(:tags, params["value"].strip, max: 5, sort_by_count: true).map(&:first).to_json
end
...@@ -117,7 +117,6 @@ use Rack::Mongoid::Middleware::IdentityMap ...@@ -117,7 +117,6 @@ use Rack::Mongoid::Middleware::IdentityMap
# these files must be required in order # these files must be required in order
require './api/search' require './api/search'
require './api/commentables' require './api/commentables'
require './api/tags'
require './api/comment_threads' require './api/comment_threads'
require './api/comments' require './api/comments'
require './api/users' require './api/users'
......
...@@ -4,10 +4,6 @@ require_relative 'content' ...@@ -4,10 +4,6 @@ require_relative 'content'
class CommentThread < Content class CommentThread < Content
include Mongoid::Timestamps include Mongoid::Timestamps
include Mongoid::TaggableWithContext
include Mongoid::TaggableWithContext::AggregationStrategy::RealTime
taggable separator: ',', default: []
voteable self, :up => +1, :down => -1 voteable self, :up => +1, :down => -1
...@@ -32,8 +28,6 @@ class CommentThread < Content ...@@ -32,8 +28,6 @@ class CommentThread < Content
mapping do mapping do
indexes :title, type: :string, analyzer: :snowball, boost: 5.0, stored: true, term_vector: :with_positions_offsets indexes :title, type: :string, analyzer: :snowball, boost: 5.0, stored: true, term_vector: :with_positions_offsets
indexes :body, type: :string, analyzer: :snowball, stored: true, term_vector: :with_positions_offsets indexes :body, type: :string, analyzer: :snowball, stored: true, term_vector: :with_positions_offsets
indexes :tags_in_text, type: :string, as: 'tags_array', index: :analyzed
indexes :tags_array, type: :string, as: 'tags_array', index: :not_analyzed, included_in_all: false
indexes :created_at, type: :date, included_in_all: false indexes :created_at, type: :date, included_in_all: false
indexes :updated_at, type: :date, included_in_all: false indexes :updated_at, type: :date, included_in_all: false
indexes :last_activity_at, type: :date, included_in_all: false indexes :last_activity_at, type: :date, included_in_all: false
...@@ -61,9 +55,6 @@ class CommentThread < Content ...@@ -61,9 +55,6 @@ class CommentThread < Content
validates_presence_of :commentable_id validates_presence_of :commentable_id
validates_presence_of :author, autosave: false validates_presence_of :author, autosave: false
validate :tag_names_valid
validate :tag_names_unique
before_create :set_last_activity_at before_create :set_last_activity_at
before_update :set_last_activity_at, :unless => lambda { closed_changed? } before_update :set_last_activity_at, :unless => lambda { closed_changed? }
...@@ -78,7 +69,6 @@ class CommentThread < Content ...@@ -78,7 +69,6 @@ class CommentThread < Content
c.commentable_id = options[:commentable_id] || "commentable_id" c.commentable_id = options[:commentable_id] || "commentable_id"
c.course_id = options[:course_id] || "course_id" c.course_id = options[:course_id] || "course_id"
c.author = options[:author] || User.first c.author = options[:author] || User.first
c.tags = options[:tags] || "test-tag-1, test-tag-2"
c.save! c.save!
c c
end end
...@@ -110,7 +100,6 @@ class CommentThread < Content ...@@ -110,7 +100,6 @@ class CommentThread < Content
search.query {|query| query.text :_all, params["text"]} if params["text"] search.query {|query| query.text :_all, params["text"]} if params["text"]
search.highlight({title: { number_of_fragments: 0 } } , {body: { number_of_fragments: 0 } }, options: { tag: "<highlight>" }) search.highlight({title: { number_of_fragments: 0 } } , {body: { number_of_fragments: 0 } }, options: { tag: "<highlight>" })
search.filter(:bool, :must => params["tags"].split(/,/).map{ |tag| { :term => { :tags_array => tag } } }) if params["tags"]
search.filter(:term, commentable_id: params["commentable_id"]) if params["commentable_id"] search.filter(:term, commentable_id: params["commentable_id"]) if params["commentable_id"]
search.filter(:terms, commentable_id: params["commentable_ids"]) if params["commentable_ids"] search.filter(:terms, commentable_id: params["commentable_ids"]) if params["commentable_ids"]
search.filter(:term, course_id: params["course_id"]) if params["course_id"] search.filter(:term, course_id: params["course_id"]) if params["course_id"]
...@@ -248,7 +237,7 @@ class CommentThread < Content ...@@ -248,7 +237,7 @@ class CommentThread < Content
# abuse_flaggers # abuse_flaggers
# from original document # from original document
# tags # tags
# from orig doc tags_array # deprecated - empty array
# type # type
# hardcoded "thread" # hardcoded "thread"
# group_id # group_id
...@@ -263,7 +252,7 @@ class CommentThread < Content ...@@ -263,7 +252,7 @@ class CommentThread < Content
"username" => author_username, "username" => author_username,
"votes" => votes.slice(*%w[count up_count down_count point]), "votes" => votes.slice(*%w[count up_count down_count point]),
"abuse_flaggers" => abuse_flaggers, "abuse_flaggers" => abuse_flaggers,
"tags" => tags_array, "tags" => [],
"type" => "thread", "type" => "thread",
"group_id" => group_id, "group_id" => group_id,
"pinned" => pinned?, "pinned" => pinned?,
...@@ -271,10 +260,6 @@ class CommentThread < Content ...@@ -271,10 +260,6 @@ class CommentThread < Content
end end
def self.tag_name_valid?(tag)
!!(tag =~ RE_TAG)
end
def comment_thread_id def comment_thread_id
#so that we can use the comment thread id as a common attribute for flagging #so that we can use the comment thread id as a common attribute for flagging
self.id self.id
...@@ -282,25 +267,6 @@ class CommentThread < Content ...@@ -282,25 +267,6 @@ class CommentThread < Content
private private
RE_HEADCHAR = /[a-z0-9]/
RE_ENDONLYCHAR = /\+/
RE_ENDCHAR = /[a-z0-9\#]/
RE_CHAR = /[a-z0-9\-\#\.]/
RE_WORD = /#{RE_HEADCHAR}(((#{RE_CHAR})*(#{RE_ENDCHAR})+)?(#{RE_ENDONLYCHAR})*)?/
RE_TAG = /^#{RE_WORD}( #{RE_WORD})*$/
def tag_names_valid
unless tags_array.all? {|tag| self.class.tag_name_valid? tag}
errors.add :tag, "can consist of words, numbers, dashes and spaces only and cannot start with dash"
end
end
def tag_names_unique
unless tags_array.uniq.size == tags_array.size
errors.add :tags, "must be unique"
end
end
def set_last_activity_at def set_last_activity_at
self.last_activity_at = Time.now.utc unless last_activity_at_changed? self.last_activity_at = Time.now.utc unless last_activity_at_changed?
end end
......
...@@ -371,25 +371,7 @@ describe "app" do ...@@ -371,25 +371,7 @@ describe "app" do
last_response.status.should == 400 last_response.status.should == 400
parse(last_response.body).first.should == I18n.t(:requested_object_not_found) parse(last_response.body).first.should == I18n.t(:requested_object_not_found)
end end
it "get information of a single comment thread with its tags" do
thread = CommentThread.new
thread.title = "new thread"
thread.body = "hahaah"
thread.course_id = "1"
thread.commentable_id = "1"
thread.author = User.first
thread.tags = "taga, tagb, tagc"
thread.save!
get "/api/v1/threads/#{thread.id}"
last_response.should be_ok
response_thread = parse last_response.body
check_thread_result(nil, thread, response_thread)
response_thread["tags"].length.should == 3
response_thread["tags"].should include "taga"
response_thread["tags"].should include "tagb"
response_thread["tags"].should include "tagc"
end
end end
describe "PUT /api/v1/threads/:thread_id" do describe "PUT /api/v1/threads/:thread_id" do
...@@ -417,22 +399,6 @@ describe "app" do ...@@ -417,22 +399,6 @@ describe "app" do
put "/api/v1/threads/#{thread.id}", body: "blocked, post...", title: "new title", commentable_id: "new_commentable_id" put "/api/v1/threads/#{thread.id}", body: "blocked, post...", title: "new title", commentable_id: "new_commentable_id"
last_response.status.should == 503 last_response.status.should == 503
end end
it "updates tag of comment thread" do
thread = CommentThread.first
put "/api/v1/threads/#{thread.id}", tags: "haha, hoho, huhu"
last_response.should be_ok
thread.reload
thread.tags_array.length.should == 3
thread.tags_array.should include "haha"
thread.tags_array.should include "hoho"
thread.tags_array.should include "huhu"
put "/api/v1/threads/#{thread.id}", tags: "aha, oho"
last_response.should be_ok
thread.reload
thread.tags_array.length.should == 2
thread.tags_array.should include "aha"
thread.tags_array.should include "oho"
end
end end
describe "POST /api/v1/threads/:thread_id/comments" do describe "POST /api/v1/threads/:thread_id/comments" do
...@@ -497,47 +463,4 @@ describe "app" do ...@@ -497,47 +463,4 @@ describe "app" do
end end
end end
end end
describe "GET /api/v1/threads/tags" do
it "get all tags used in threads" do
CommentThread.recalculate_all_context_tag_weights!
thread1 = CommentThread.all.to_a.first
thread2 = CommentThread.all.to_a.last
thread1.tags = "a, b, c"
thread1.save
thread2.tags = "d, e, f"
thread2.save
get "/api/v1/threads/tags"
last_response.should be_ok
tags = parse last_response.body
tags.length.should == 6
end
end
describe "GET /api/v1/threads/tags/autocomplete" do
def create_comment_thread(tags)
c = CommentThread.new(title: "Interesting question", body: "cool")
c.course_id = "1"
c.author = User.first
c.tags = tags
c.commentable_id = "1"
c.save!
c
end
it "returns autocomplete results" do
CommentThread.delete_all
CommentThread.recalculate_all_context_tag_weights!
create_comment_thread "c++, clojure, common-lisp, c#, c, coffeescript"
create_comment_thread "c++, clojure, common-lisp, c#, c"
create_comment_thread "c++, clojure, common-lisp, c#"
create_comment_thread "c++, clojure, common-lisp"
create_comment_thread "c++, clojure"
create_comment_thread "c++"
get "/api/v1/threads/tags/autocomplete", value: "c"
last_response.should be_ok
results = parse last_response.body
results.length.should == 5
%w[c++ clojure common-lisp c# c].each_with_index do |tag, index|
results[index].should == tag
end
end
end
end end
...@@ -101,36 +101,6 @@ describe "app" do ...@@ -101,36 +101,6 @@ describe "app" do
last_response.status.should == 503 last_response.status.should == 503
parse(last_response.body).first.should == I18n.t(:blocked_content_with_body_hash, :hash => Digest::MD5.hexdigest("blocked post")) parse(last_response.body).first.should == I18n.t(:blocked_content_with_body_hash, :hash => Digest::MD5.hexdigest("blocked post"))
end end
it "create a new comment thread with tag" do
old_count = CommentThread.count
post '/api/v1/question_1/threads', default_params.merge(tags: "a, b, c")
last_response.should be_ok
CommentThread.count.should == old_count + 1
thread = CommentThread.where(title: "Interesting question").first
thread.tags_array.length.should == 3
thread.tags_array.should include "a"
thread.tags_array.should include "b"
thread.tags_array.should include "c"
end
it "strip spaces in tags" do
old_count = CommentThread.count
post '/api/v1/question_1/threads', default_params.merge(tags: " a, b ,c ")
last_response.should be_ok
CommentThread.count.should == old_count + 1
thread = CommentThread.where(title: "Interesting question").first
thread.tags_array.length.should == 3
thread.tags_array.should include "a"
thread.tags_array.should include "b"
thread.tags_array.should include "c"
end
it "accepts [a-z 0-9 + # - .]words, numbers, dashes, spaces but no underscores in tags" do
old_count = CommentThread.count
post '/api/v1/question_1/threads', default_params.merge(tags: "artificial-intelligence, machine-learning, 7-is-a-lucky-number, interesting problem, interesting problems in c++")
last_response.should be_ok
CommentThread.count.should == old_count + 1
thread = CommentThread.where(title: "Interesting question").first
thread.tags_array.length.should == 5
end
end end
end end
end end
require 'spec_helper'
describe "app" do
describe "search" do
before(:each) { init_without_subscriptions }
describe "GET /api/v1/search/threads" do
it "returns all threads tagged with all tags" do
thread1 = CommentThread.all.to_a.first
thread2 = CommentThread.all.to_a.last
ai = "artificial intelligence"
ml = "marchine learning"
random1 = "random1"
random2 = "random2"
random3 = "random3"
thread1.tags = [ai, ml, random1].join ","
thread1.save
thread2.tags = [ai, ml, random2].join ","
thread2.save
sleep 1
get "/api/v1/search/threads", tags: [ai, ml].join(",")
last_response.should be_ok
threads = parse(last_response.body)['collection']
threads.length.should == 2
check_thread_result(nil, thread1, threads.select{|t| t["id"] == thread1.id.to_s}.first, false, true)
check_thread_result(nil, thread2, threads.select{|t| t["id"] == thread2.id.to_s}.first, false, true)
get "/api/v1/search/threads", tags: [ai].join(",")
last_response.should be_ok
threads = parse(last_response.body)['collection']
threads.length.should == 2
check_thread_result(nil, thread1, threads.select{|t| t["id"] == thread1.id.to_s}.first, false, true)
check_thread_result(nil, thread2, threads.select{|t| t["id"] == thread2.id.to_s}.first, false, true)
get "/api/v1/search/threads", tags: [ai, random1].join(",")
last_response.should be_ok
threads = parse(last_response.body)['collection']
threads.length.should == 1
check_thread_result(nil, thread1, threads.select{|t| t["id"] == thread1.id.to_s}.first, false, true)
get "/api/v1/search/threads", tags: [random1].join(",")
last_response.should be_ok
threads = parse(last_response.body)['collection']
threads.length.should == 1
check_thread_result(nil, thread1, threads.select{|t| t["id"] == thread1.id.to_s}.first, false, true)
get "/api/v1/search/threads", tags: [random1, random2].join(",")
last_response.should be_ok
threads = parse(last_response.body)['collection']
threads.length.should == 0
end
end
end
end
require 'spec_helper' require 'spec_helper'
describe CommentThread do describe CommentThread do
it "validates tag name" do
CommentThread.tag_name_valid?("a++").should be_true
CommentThread.tag_name_valid?("a++ b++ c++").should be_true
CommentThread.tag_name_valid?("a#b+").should be_true
CommentThread.tag_name_valid?("a##").should be_true
CommentThread.tag_name_valid?("a#-b#").should be_true
CommentThread.tag_name_valid?("000a123").should be_true
CommentThread.tag_name_valid?("artificial-intelligence").should be_true
CommentThread.tag_name_valid?("artificial intelligence").should be_true
CommentThread.tag_name_valid?("well-known formulas").should be_true
CommentThread.tag_name_valid?("a#+b#").should be_false
CommentThread.tag_name_valid?("a# +b#").should be_false
CommentThread.tag_name_valid?("--a").should be_false
CommentThread.tag_name_valid?("artificial_intelligence").should be_false
CommentThread.tag_name_valid?("#this-is-a-tag").should be_false
CommentThread.tag_name_valid?("_this-is-a-tag").should be_false
CommentThread.tag_name_valid?("this-is+a-tag").should be_false
end
context "endorsed?" do context "endorsed?" do
......
...@@ -200,7 +200,7 @@ def check_thread_result(user, thread, json_response, check_comments=false, is_se ...@@ -200,7 +200,7 @@ def check_thread_result(user, thread, json_response, check_comments=false, is_se
json_response["votes"]["up_count"].should == thread.votes["up_count"] json_response["votes"]["up_count"].should == thread.votes["up_count"]
json_response["votes"]["down_count"].should == thread.votes["down_count"] json_response["votes"]["down_count"].should == thread.votes["down_count"]
json_response["abuse_flaggers"].should == thread.abuse_flaggers json_response["abuse_flaggers"].should == thread.abuse_flaggers
json_response["tags"].should == thread.tags_array json_response["tags"].should == []
json_response["type"].should == "thread" json_response["type"].should == "thread"
json_response["group_id"].should == thread.group_id json_response["group_id"].should == thread.group_id
json_response["pinned"].should == thread.pinned? json_response["pinned"].should == thread.pinned?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment