added related tag query model, fixes to related tag calculator
This commit is contained in:
46
app/logical/related_tag_query.rb
Normal file
46
app/logical/related_tag_query.rb
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
class RelatedTagQuery
|
||||||
|
attr_reader :query, :category
|
||||||
|
|
||||||
|
def initialize(query, category)
|
||||||
|
@query = query
|
||||||
|
@category = category
|
||||||
|
end
|
||||||
|
|
||||||
|
def tags
|
||||||
|
if query =~ /\*/
|
||||||
|
pattern_matching_tags
|
||||||
|
elsif category.present?
|
||||||
|
related_tags_by_category
|
||||||
|
else
|
||||||
|
related_tags
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wiki_page_tags
|
||||||
|
wiki_page.try(:tags) || []
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def pattern_matching_tags
|
||||||
|
Tag.name_matches(query).order("post_count desc").limit(50).sort_by {|x| x.name}.map(&:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def related_tags
|
||||||
|
tag = Tag.named(query).first
|
||||||
|
|
||||||
|
if tag
|
||||||
|
tag.related_tag_array.map(&:first)
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def related_tags_by_category
|
||||||
|
RelatedTagCalculator.calculate_from_sample_to_array(query, Tag.categories.value_for(category)).map(&:first)
|
||||||
|
end
|
||||||
|
|
||||||
|
def wiki_page
|
||||||
|
WikiPage.titled(query).first
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2,7 +2,8 @@ class Tag < ActiveRecord::Base
|
|||||||
attr_accessible :category
|
attr_accessible :category
|
||||||
after_save :update_category_cache
|
after_save :update_category_cache
|
||||||
has_one :wiki_page, :foreign_key => "name", :primary_key => "title"
|
has_one :wiki_page, :foreign_key => "name", :primary_key => "title"
|
||||||
scope :name_matches, lambda {|name| where(["name LIKE ? ESCAPE E'\\\\'", name.to_escaped_for_sql_like])}
|
scope :name_matches, lambda {|name| where("name LIKE ? ESCAPE E'\\\\'", name.to_escaped_for_sql_like)}
|
||||||
|
scope :named, lambda {|name| where("name = ?", TagAlias.to_aliased([name]).join(""))}
|
||||||
search_methods :name_matches
|
search_methods :name_matches
|
||||||
|
|
||||||
class CategoryMapping
|
class CategoryMapping
|
||||||
@@ -310,8 +311,9 @@ class Tag < ActiveRecord::Base
|
|||||||
module RelationMethods
|
module RelationMethods
|
||||||
def update_related
|
def update_related
|
||||||
return unless should_update_related?
|
return unless should_update_related?
|
||||||
counts = RelatedTagCalculator.calculate_from_sample(Danbooru.config.post_sample_size, name)
|
self.related_tags = RelatedTagCalculator.calculate_from_sample_to_array(name).join(" ")
|
||||||
update_attributes(:related_tags => RelatedTagCalculator.convert_hash_to_string(counts), :related_tags_updated_at => Time.now)
|
self.related_tags_updated_at = Time.now
|
||||||
|
save
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_related_if_outdated
|
def update_related_if_outdated
|
||||||
|
|||||||
@@ -88,4 +88,14 @@ class WikiPage < ActiveRecord::Base
|
|||||||
def presenter
|
def presenter
|
||||||
@presenter ||= WikiPagePresenter.new(self)
|
@presenter ||= WikiPagePresenter.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tags
|
||||||
|
body.scan(/\[\[(.+?)\]\]/).flatten.map do |match|
|
||||||
|
if match =~ /^(.+?)\|(.+)/
|
||||||
|
$1
|
||||||
|
else
|
||||||
|
match
|
||||||
|
end
|
||||||
|
end.map {|x| x.downcase.tr(" ", "_")}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
74
test/unit/related_tag_query_test.rb
Normal file
74
test/unit/related_tag_query_test.rb
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class RelatedTagQueryTest < ActiveSupport::TestCase
|
||||||
|
setup do
|
||||||
|
user = Factory.create(:user)
|
||||||
|
CurrentUser.user = user
|
||||||
|
CurrentUser.ip_addr = "127.0.0.1"
|
||||||
|
MEMCACHE.flush_all
|
||||||
|
Delayed::Worker.delay_jobs = false
|
||||||
|
end
|
||||||
|
|
||||||
|
context "a related tag query without a category constraint" do
|
||||||
|
setup do
|
||||||
|
@post_1 = Factory.create(:post, :tag_string => "aaa bbb")
|
||||||
|
@post_2 = Factory.create(:post, :tag_string => "aaa bbb ccc")
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for a tag that already exists" do
|
||||||
|
setup do
|
||||||
|
Tag.named("aaa").first.update_related
|
||||||
|
@query = RelatedTagQuery.new("aaa", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "work" do
|
||||||
|
assert_equal(["aaa", "bbb", "ccc"], @query.tags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for a tag that doesn't exist" do
|
||||||
|
setup do
|
||||||
|
@query = RelatedTagQuery.new("zzz", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "work" do
|
||||||
|
assert_equal([], @query.tags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for a pattern search" do
|
||||||
|
setup do
|
||||||
|
@query = RelatedTagQuery.new("a*", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "work" do
|
||||||
|
assert_equal(["aaa"], @query.tags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for a tag with a wiki page" do
|
||||||
|
setup do
|
||||||
|
@wiki_page = Factory.create(:wiki_page, :title => "aaa", :body => "[[bbb]] [[ccc]]")
|
||||||
|
@query = RelatedTagQuery.new("aaa", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "find any tags embedded in the wiki page" do
|
||||||
|
assert_equal(["bbb", "ccc"], @query.wiki_page_tags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "a related tag query with a category constraint" do
|
||||||
|
setup do
|
||||||
|
@post_1 = Factory.create(:post, :tag_string => "aaa bbb")
|
||||||
|
@post_2 = Factory.create(:post, :tag_string => "aaa art:ccc")
|
||||||
|
@post_3 = Factory.create(:post, :tag_string => "aaa copy:ddd")
|
||||||
|
@query = RelatedTagQuery.new("aaa", "artist")
|
||||||
|
end
|
||||||
|
|
||||||
|
should "find the related tags" do
|
||||||
|
assert_equal(%w(ccc), @query.tags)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Reference in New Issue
Block a user