* Removed memcaching for TagImplication (too many latent race conditions)
* Added Post.exact_tag_match to skip normalization/metatag parsing * Added DelayedJob support for tag alias/implication processing
This commit is contained in:
25
Gemfile.lock
25
Gemfile.lock
@@ -46,7 +46,7 @@ GEM
|
|||||||
activesupport (= 3.1.0.rc1)
|
activesupport (= 3.1.0.rc1)
|
||||||
activesupport (3.1.0.rc1)
|
activesupport (3.1.0.rc1)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
arel (2.1.3)
|
arel (2.1.4)
|
||||||
bcrypt-ruby (2.1.4)
|
bcrypt-ruby (2.1.4)
|
||||||
builder (3.0.0)
|
builder (3.0.0)
|
||||||
daemons (1.1.4)
|
daemons (1.1.4)
|
||||||
@@ -54,9 +54,9 @@ GEM
|
|||||||
activesupport (~> 3.0)
|
activesupport (~> 3.0)
|
||||||
daemons
|
daemons
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
factory_girl (1.3.3)
|
factory_girl (2.0.2)
|
||||||
haml (3.1.2)
|
haml (3.1.2)
|
||||||
hike (1.1.0)
|
hike (1.2.0)
|
||||||
i18n (0.6.0)
|
i18n (0.6.0)
|
||||||
imagesize (0.1.1)
|
imagesize (0.1.1)
|
||||||
mail (2.3.0)
|
mail (2.3.0)
|
||||||
@@ -64,10 +64,10 @@ GEM
|
|||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
treetop (~> 1.4.8)
|
treetop (~> 1.4.8)
|
||||||
mechanize (2.0.1)
|
mechanize (2.0.1)
|
||||||
net-http-digest_auth (~> 1.1, >= 1.1.1)
|
net-http-digest_auth (>= 1.1.1, ~> 1.1)
|
||||||
net-http-persistent (~> 1.8)
|
net-http-persistent (~> 1.8)
|
||||||
nokogiri (~> 1.4)
|
nokogiri (~> 1.4)
|
||||||
webrobots (~> 0.0, >= 0.0.9)
|
webrobots (>= 0.0.9, ~> 0.0)
|
||||||
memcache-client (1.8.5)
|
memcache-client (1.8.5)
|
||||||
mime-types (1.16)
|
mime-types (1.16)
|
||||||
mocha (0.9.12)
|
mocha (0.9.12)
|
||||||
@@ -76,15 +76,15 @@ GEM
|
|||||||
net-http-persistent (1.8)
|
net-http-persistent (1.8)
|
||||||
nokogiri (1.5.0)
|
nokogiri (1.5.0)
|
||||||
pg (0.11.0)
|
pg (0.11.0)
|
||||||
polyglot (0.3.1)
|
polyglot (0.3.2)
|
||||||
rack (1.3.1)
|
rack (1.3.2)
|
||||||
rack-cache (1.0.2)
|
rack-cache (1.0.2)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
rack-mount (0.8.1)
|
rack-mount (0.8.1)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rack-ssl (1.3.2)
|
rack-ssl (1.3.2)
|
||||||
rack
|
rack
|
||||||
rack-test (0.6.0)
|
rack-test (0.6.1)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (3.1.0.rc1)
|
rails (3.1.0.rc1)
|
||||||
actionmailer (= 3.1.0.rc1)
|
actionmailer (= 3.1.0.rc1)
|
||||||
@@ -109,16 +109,17 @@ GEM
|
|||||||
simplecov (0.4.2)
|
simplecov (0.4.2)
|
||||||
simplecov-html (~> 0.4.4)
|
simplecov-html (~> 0.4.4)
|
||||||
simplecov-html (0.4.5)
|
simplecov-html (0.4.5)
|
||||||
sprockets (2.0.0.beta.10)
|
sprockets (2.0.0.beta.12)
|
||||||
hike (~> 1.0)
|
hike (~> 1.2)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (!= 1.3.0, ~> 1.1)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
super_exception_notifier (3.0.13)
|
super_exception_notifier (3.0.13)
|
||||||
actionmailer
|
actionmailer
|
||||||
rake
|
rake
|
||||||
thor (0.14.6)
|
thor (0.14.6)
|
||||||
tilt (1.3.2)
|
tilt (1.3.2)
|
||||||
treetop (1.4.9)
|
treetop (1.4.10)
|
||||||
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
tzinfo (0.3.29)
|
tzinfo (0.3.29)
|
||||||
webrobots (0.0.10)
|
webrobots (0.0.10)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class TagAliasesController < ApplicationController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
@tag_alias = TagAlias.create(params[:tag_alias])
|
@tag_alias = TagAlias.create(params[:tag_alias])
|
||||||
|
@tag_alias.delay.process!
|
||||||
respond_with(@tag_alias, :location => tag_aliases_path(:search => {:id_eq => @tag_alias.id}))
|
respond_with(@tag_alias, :location => tag_aliases_path(:search => {:id_eq => @tag_alias.id}))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class TagImplicationsController < ApplicationController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
@tag_implication = TagImplication.create(params[:tag_implication])
|
@tag_implication = TagImplication.create(params[:tag_implication])
|
||||||
|
@tag_implication.delay.process!
|
||||||
respond_with(@tag_implication, :location => tag_implications_path(:search => {:id_eq => @tag_implication.id}))
|
respond_with(@tag_implication, :location => tag_implications_path(:search => {:id_eq => @tag_implication.id}))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class Post < ActiveRecord::Base
|
|||||||
scope :available_for_moderation, lambda {where(["id NOT IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])}
|
scope :available_for_moderation, lambda {where(["id NOT IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])}
|
||||||
scope :hidden_from_moderation, lambda {where(["id IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])}
|
scope :hidden_from_moderation, lambda {where(["id IN (SELECT pd.post_id FROM post_disapprovals pd WHERE pd.user_id = ?)", CurrentUser.id])}
|
||||||
scope :tag_match, lambda {|query| Post.tag_match_helper(query)}
|
scope :tag_match, lambda {|query| Post.tag_match_helper(query)}
|
||||||
|
scope :exact_tag_match, lambda {|query| Post.exact_tag_match_helper(query)}
|
||||||
scope :positive, where("score > 1")
|
scope :positive, where("score > 1")
|
||||||
scope :negative, where("score < -1")
|
scope :negative, where("score < -1")
|
||||||
search_methods :tag_match
|
search_methods :tag_match
|
||||||
@@ -501,6 +502,11 @@ class Post < ActiveRecord::Base
|
|||||||
|
|
||||||
relation
|
relation
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def exact_tag_match_helper(q)
|
||||||
|
arel = Post.scoped
|
||||||
|
add_tag_string_search_relation({:related => [q].flatten, :include => [], :exclude => []}, arel)
|
||||||
|
end
|
||||||
|
|
||||||
def tag_match_helper(q)
|
def tag_match_helper(q)
|
||||||
unless q.is_a?(Hash)
|
unless q.is_a?(Hash)
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
class TagAlias < ActiveRecord::Base
|
class TagAlias < ActiveRecord::Base
|
||||||
attr_accessor :creator_ip_addr
|
before_save :clear_all_cache
|
||||||
after_save :update_posts
|
|
||||||
after_save :clear_cache
|
|
||||||
after_save :clear_remote_cache
|
|
||||||
after_save :update_cache
|
after_save :update_cache
|
||||||
after_destroy :clear_cache
|
after_destroy :clear_all_cache
|
||||||
after_destroy :clear_remote_cache
|
|
||||||
before_validation :initialize_creator, :on => :create
|
before_validation :initialize_creator, :on => :create
|
||||||
validates_presence_of :creator_id
|
validates_presence_of :creator_id
|
||||||
validates_uniqueness_of :antecedent_name
|
validates_uniqueness_of :antecedent_name
|
||||||
@@ -25,8 +21,17 @@ class TagAlias < ActiveRecord::Base
|
|||||||
alias_hash.values.flatten.uniq
|
alias_hash.values.flatten.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def process!
|
||||||
|
update_column(:status, "processing")
|
||||||
|
update_posts
|
||||||
|
update_column(:status, "active")
|
||||||
|
rescue Exception => e
|
||||||
|
update_column(:status, "error: #{e}")
|
||||||
|
end
|
||||||
|
|
||||||
def initialize_creator
|
def initialize_creator
|
||||||
self.creator_id = CurrentUser.user.id
|
self.creator_id = CurrentUser.user.id
|
||||||
|
self.creator_ip_addr = CurrentUser.ip_addr
|
||||||
end
|
end
|
||||||
|
|
||||||
def antecedent_tag
|
def antecedent_tag
|
||||||
@@ -44,6 +49,11 @@ class TagAlias < ActiveRecord::Base
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def clear_all_cache
|
||||||
|
clear_cache
|
||||||
|
clear_remote_cache
|
||||||
|
end
|
||||||
|
|
||||||
def clear_cache
|
def clear_cache
|
||||||
Cache.delete("ta:#{Cache.sanitize(antecedent_name)}")
|
Cache.delete("ta:#{Cache.sanitize(antecedent_name)}")
|
||||||
@@ -60,13 +70,15 @@ class TagAlias < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_posts
|
def update_posts
|
||||||
Post.tag_match(antecedent_name).find_each do |post|
|
Post.exact_tag_match(antecedent_name).find_each do |post|
|
||||||
escaped_antecedent_name = Regexp.escape(antecedent_name)
|
escaped_antecedent_name = Regexp.escape(antecedent_name)
|
||||||
fixed_tags = post.tag_string.sub(/(?:\A| )#{escaped_antecedent_name}(?:\Z| )/, " #{consequent_name} ").strip
|
fixed_tags = post.tag_string.sub(/(?:\A| )#{escaped_antecedent_name}(?:\Z| )/, " #{consequent_name} ").strip
|
||||||
|
|
||||||
post.update_attributes(
|
CurrentUser.scoped(creator, creator_ip_addr) do
|
||||||
:tag_string => fixed_tags
|
post.update_attributes(
|
||||||
)
|
:tag_string => fixed_tags
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,43 +1,19 @@
|
|||||||
class TagImplication < ActiveRecord::Base
|
class TagImplication < ActiveRecord::Base
|
||||||
before_save :clear_cache
|
|
||||||
before_save :update_descendant_names
|
before_save :update_descendant_names
|
||||||
after_save :update_descendant_names_for_parent
|
after_save :update_descendant_names_for_parent
|
||||||
after_save :update_cache
|
|
||||||
after_save :update_posts
|
|
||||||
after_destroy :clear_cache
|
|
||||||
after_destroy :clear_remote_cache
|
|
||||||
belongs_to :creator, :class_name => "User"
|
belongs_to :creator, :class_name => "User"
|
||||||
before_validation :initialize_creator, :on => :create
|
before_validation :initialize_creator, :on => :create
|
||||||
validates_presence_of :creator_id
|
validates_presence_of :creator_id
|
||||||
validates_uniqueness_of :antecedent_name, :scope => :consequent_name
|
validates_uniqueness_of :antecedent_name, :scope => :consequent_name
|
||||||
validate :absence_of_circular_relation
|
validate :absence_of_circular_relation
|
||||||
|
|
||||||
module CacheMethods
|
|
||||||
def clear_cache
|
|
||||||
Cache.delete("ti:#{Cache.sanitize(antecedent_name)}")
|
|
||||||
@descendants = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear_remote_cache
|
|
||||||
Danbooru.config.other_server_hosts.each do |server|
|
|
||||||
Net::HTTP.delete(URI.parse("http://#{server}/tag_implications/#{id}/cache"))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_cache
|
|
||||||
descendant_names_array
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module DescendantMethods
|
module DescendantMethods
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
|
# assumes names are normalized
|
||||||
def with_descendants(names)
|
def with_descendants(names)
|
||||||
names + Cache.get_multi(names.flatten, "ti") do |name|
|
(names + where("antecedent_name in (?)", names).map(&:descendant_names_array)).flatten.uniq
|
||||||
([name] + where(["antecedent_name = ?", name]).all.map {|x| x.descendant_names_array}).flatten
|
|
||||||
end.values.flatten.uniq
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -55,9 +31,7 @@ class TagImplication < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def descendant_names_array
|
def descendant_names_array
|
||||||
Cache.get("ti:#{Cache.sanitize(antecedent_name)}") do
|
descendant_names.split(/ /)
|
||||||
descendant_names.split(/ /)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_descendant_names
|
def update_descendant_names
|
||||||
@@ -93,12 +67,20 @@ class TagImplication < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
include CacheMethods
|
|
||||||
include DescendantMethods
|
include DescendantMethods
|
||||||
include ParentMethods
|
include ParentMethods
|
||||||
|
|
||||||
def initialize_creator
|
def initialize_creator
|
||||||
self.creator_id = CurrentUser.user.id
|
self.creator_id = CurrentUser.user.id
|
||||||
|
self.creator_ip_addr = CurrentUser.ip_addr
|
||||||
|
end
|
||||||
|
|
||||||
|
def process!
|
||||||
|
update_column(:status, "processing")
|
||||||
|
update_posts
|
||||||
|
update_column(:status, "active")
|
||||||
|
rescue Exception => e
|
||||||
|
update_column(:status, "error: #{e}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def absence_of_circular_relation
|
def absence_of_circular_relation
|
||||||
@@ -110,12 +92,14 @@ class TagImplication < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_posts
|
def update_posts
|
||||||
Post.tag_match(antecedent_name).find_each do |post|
|
Post.exact_tag_match(antecedent_name).find_each do |post|
|
||||||
escaped_antecedent_name = Regexp.escape(antecedent_name)
|
escaped_antecedent_name = Regexp.escape(antecedent_name)
|
||||||
fixed_tags = post.tag_string.sub(/(?:\A| )#{escaped_antecedent_name}(?:\Z| )/, " #{antecedent_name} #{descendant_names} ").strip
|
fixed_tags = post.tag_string.sub(/(?:\A| )#{escaped_antecedent_name}(?:\Z| )/, " #{antecedent_name} #{descendant_names} ").strip
|
||||||
post.update_attributes(
|
CurrentUser.scoped(creator, creator_ip_addr) do
|
||||||
:tag_string => fixed_tags
|
post.update_attributes(
|
||||||
)
|
:tag_string => fixed_tags
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
<div id="jquery-test">
|
|
||||||
<div class="note" id="lots-of-text-1">
|
|
||||||
Lorem ipsum
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="note" id="lots-of-text-2" style="left: 400px;">
|
|
||||||
Lorem ipsum
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var body = $("#lots-of-text-2");
|
|
||||||
body.css({height: "auto", minWidth: 140});
|
|
||||||
|
|
||||||
var w = body[0].offsetWidth;
|
|
||||||
var h = body[0].offsetHeight;
|
|
||||||
var lo = null;
|
|
||||||
var hi = null;
|
|
||||||
var x = null;
|
|
||||||
var last = null;
|
|
||||||
|
|
||||||
if (body[0].scrollWidth <= body[0].clientWidth) {
|
|
||||||
lo = 20, hi = w
|
|
||||||
|
|
||||||
do {
|
|
||||||
x = (lo+hi)/2
|
|
||||||
body.css({minWidth: x});
|
|
||||||
|
|
||||||
if (body[0].offsetHeight > h) {
|
|
||||||
lo = x;
|
|
||||||
} else {
|
|
||||||
hi = x;
|
|
||||||
}
|
|
||||||
} while ((hi - lo) > 4);
|
|
||||||
|
|
||||||
if (body[0].offsetHeight > h) {
|
|
||||||
body.css({minWidth: hi});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<div style="width: 40em; margin: 5em auto; overflow: scroll;">
|
<div style="width: 40em; margin: 5em auto; overflow: scroll;">
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h4>Terms of Service</h4>
|
<h1>Terms of Service</h1>
|
||||||
<p>By accessing the "<%= Danbooru.config.app_name %>" website ("Site") you agree to the following terms of service. If you do not agree to these terms, then please do not access the Site.</p>
|
<p>By accessing the "<%= Danbooru.config.app_name %>" website ("Site") you agree to the following terms of service. If you do not agree to these terms, then please do not access the Site.</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
@@ -13,13 +13,13 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h6>Post/Comment Limiting</h6>
|
<h1>Post/Comment Limiting</h1>
|
||||||
<p>You cannot upload a post or comment during the first week of signing up.</p>
|
<p>You cannot upload a post or comment during the first week of signing up.</p>
|
||||||
<p>After the initial period, you can post up to one comment an hour and a variable number of posts based on how many of your previous uploads were approved or deleted.</p>
|
<p>After the initial period, you can post up to one comment an hour and a variable number of posts based on how many of your previous uploads were approved or deleted.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h6>Prohibited Content</h6>
|
<h1>Prohibited Content</h1>
|
||||||
<p>In addition, you may not use the Site to upload any of the following:</p>
|
<p>In addition, you may not use the Site to upload any of the following:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Non-anime: Photographs of American porn actresses, for example, are prohibited. Photographs of cosplayers, figures, or prominent figures in the industry are acceptable.</li>
|
<li>Non-anime: Photographs of American porn actresses, for example, are prohibited. Photographs of cosplayers, figures, or prominent figures in the industry are acceptable.</li>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h4>Copyright Infringement</h4>
|
<h1>Copyright Infringement</h1>
|
||||||
|
|
||||||
<p>If you believe a post infringes upon your copyright, please send an email to the <%= mail_to Danbooru.config.contact_email, "webmaster", :encode => "hex" %> with the following pieces of information:</p>
|
<p>If you believe a post infringes upon your copyright, please send an email to the <%= mail_to Danbooru.config.contact_email, "webmaster", :encode => "hex" %> with the following pieces of information:</p>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -45,14 +45,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h4>Privacy Policy</h4>
|
<h1>Privacy Policy</h1>
|
||||||
|
|
||||||
<p>The Site will not disclose the IP address, email address, password, or DMails of any user except to the staff.</p>
|
<p>The Site will not disclose the IP address, email address, password, or DMails of any user except to the staff.</p>
|
||||||
<p>The Site is allowed to make public everything else, including but not limited to: uploaded posts, favorited posts, comments, forum posts, wiki edits, and note edits.</p>
|
<p>The Site is allowed to make public everything else, including but not limited to: uploaded posts, favorited posts, comments, forum posts, wiki edits, and note edits.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4>Agreement</h4>
|
<h1>Agreement</h1>
|
||||||
<p>By clicking on the "I Agree" link, you have read all the terms and have agreed to them.</p>
|
<p>By clicking on the "I Agree" link, you have read all the terms and have agreed to them.</p>
|
||||||
<p><%= link_to("I Agree", params[:url] || "/", :onclick => "Cookie.put('tos', '1')") %> | <%= link_to("Cancel", "/") %></p>
|
<p><%= link_to("I Agree", params[:url] || "/", :onclick => "Cookie.put('tos', '1')") %> | <%= link_to("Cancel", "/") %></p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2250,7 +2250,9 @@ CREATE TABLE tag_aliases (
|
|||||||
antecedent_name character varying(255) NOT NULL,
|
antecedent_name character varying(255) NOT NULL,
|
||||||
consequent_name character varying(255) NOT NULL,
|
consequent_name character varying(255) NOT NULL,
|
||||||
creator_id integer NOT NULL,
|
creator_id integer NOT NULL,
|
||||||
|
creator_ip_addr inet NOT NULL,
|
||||||
forum_topic_id integer,
|
forum_topic_id integer,
|
||||||
|
status character varying(255) DEFAULT 'pending'::character varying NOT NULL,
|
||||||
created_at timestamp without time zone,
|
created_at timestamp without time zone,
|
||||||
updated_at timestamp without time zone
|
updated_at timestamp without time zone
|
||||||
);
|
);
|
||||||
@@ -2285,7 +2287,9 @@ CREATE TABLE tag_implications (
|
|||||||
consequent_name character varying(255) NOT NULL,
|
consequent_name character varying(255) NOT NULL,
|
||||||
descendant_names text NOT NULL,
|
descendant_names text NOT NULL,
|
||||||
creator_id integer NOT NULL,
|
creator_id integer NOT NULL,
|
||||||
|
creator_ip_addr inet NOT NULL,
|
||||||
forum_topic_id integer,
|
forum_topic_id integer,
|
||||||
|
status character varying(255) DEFAULT 'pending'::character varying NOT NULL,
|
||||||
created_at timestamp without time zone,
|
created_at timestamp without time zone,
|
||||||
updated_at timestamp without time zone
|
updated_at timestamp without time zone
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ class CreateTagAliases < ActiveRecord::Migration
|
|||||||
t.column :antecedent_name, :string, :null => false
|
t.column :antecedent_name, :string, :null => false
|
||||||
t.column :consequent_name, :string, :null => false
|
t.column :consequent_name, :string, :null => false
|
||||||
t.column :creator_id, :integer, :null => false
|
t.column :creator_id, :integer, :null => false
|
||||||
|
t.column :creator_ip_addr, :inet, :null => false
|
||||||
t.column :forum_topic_id, :integer
|
t.column :forum_topic_id, :integer
|
||||||
|
t.column :status, :text, :null => false, :default => "pending"
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ class CreateTagImplications < ActiveRecord::Migration
|
|||||||
t.column :consequent_name, :string, :null => false
|
t.column :consequent_name, :string, :null => false
|
||||||
t.column :descendant_names, :text, :null => false
|
t.column :descendant_names, :text, :null => false
|
||||||
t.column :creator_id, :integer, :null => false
|
t.column :creator_id, :integer, :null => false
|
||||||
|
t.column :creator_ip_addr, :inet, :null => false
|
||||||
t.column :forum_topic_id, :integer
|
t.column :forum_topic_id, :integer
|
||||||
|
t.column :status, :text, :null => false, :default => "pending"
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
psql -c "UPDATE posts SET is_flagged = false, is_pending = true, approver_id = null WHERE id = 1" danbooru2
|
|
||||||
psql -c "DELETE FROM unapprovals" danbooru2
|
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
Factory.define(:tag_alias) do |f|
|
FactoryGirl.define do
|
||||||
f.antecedent_name "aaa"
|
factory :tag_alias do
|
||||||
f.consequent_name "bbb"
|
antecedent_name "aaa"
|
||||||
|
consequent_name "bbb"
|
||||||
|
|
||||||
|
after_create do |tag_alias|
|
||||||
|
tag_alias.process!
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
Factory.define(:tag_implication) do |f|
|
FactoryGirl.define do
|
||||||
f.antecedent_name "aaa"
|
factory :tag_implication do
|
||||||
f.consequent_name "bbb"
|
antecedent_name "aaa"
|
||||||
|
consequent_name "bbb"
|
||||||
|
|
||||||
|
after_create do |tag_implication|
|
||||||
|
tag_implication.process!
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class TagAliasesControllerTest < ActionController::TestCase
|
|||||||
CurrentUser.user = @user
|
CurrentUser.user = @user
|
||||||
CurrentUser.ip_addr = "127.0.0.1"
|
CurrentUser.ip_addr = "127.0.0.1"
|
||||||
MEMCACHE.flush_all
|
MEMCACHE.flush_all
|
||||||
|
Delayed::Worker.delay_jobs = false
|
||||||
end
|
end
|
||||||
|
|
||||||
teardown do
|
teardown do
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class TagImplicationsControllerTest < ActionController::TestCase
|
|||||||
CurrentUser.user = @user
|
CurrentUser.user = @user
|
||||||
CurrentUser.ip_addr = "127.0.0.1"
|
CurrentUser.ip_addr = "127.0.0.1"
|
||||||
MEMCACHE.flush_all
|
MEMCACHE.flush_all
|
||||||
|
Delayed::Worker.delay_jobs = false
|
||||||
end
|
end
|
||||||
|
|
||||||
teardown do
|
teardown do
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require_relative '../test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class TagAliasTest < ActiveSupport::TestCase
|
class TagAliasTest < ActiveSupport::TestCase
|
||||||
context "A tag alias" do
|
context "A tag alias" do
|
||||||
@@ -15,14 +15,14 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "populate the creator information" do
|
should "populate the creator information" do
|
||||||
ta = Factory.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ta = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
assert_equal(CurrentUser.user.id, ta.creator_id)
|
assert_equal(CurrentUser.user.id, ta.creator_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
should "convert a tag to its normalized version" do
|
should "convert a tag to its normalized version" do
|
||||||
tag1 = Factory.create(:tag, :name => "aaa")
|
tag1 = Factory.create(:tag, :name => "aaa")
|
||||||
tag2 = Factory.create(:tag, :name => "bbb")
|
tag2 = Factory.create(:tag, :name => "bbb")
|
||||||
ta = Factory.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ta = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
normalized_tags = TagAlias.to_aliased(["aaa", "ccc"])
|
normalized_tags = TagAlias.to_aliased(["aaa", "ccc"])
|
||||||
assert_equal(["bbb", "ccc"], normalized_tags.sort)
|
assert_equal(["bbb", "ccc"], normalized_tags.sort)
|
||||||
end
|
end
|
||||||
@@ -30,7 +30,7 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
should "update the cache" do
|
should "update the cache" do
|
||||||
tag1 = Factory.create(:tag, :name => "aaa")
|
tag1 = Factory.create(:tag, :name => "aaa")
|
||||||
tag2 = Factory.create(:tag, :name => "bbb")
|
tag2 = Factory.create(:tag, :name => "bbb")
|
||||||
ta = Factory.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ta = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
assert_equal("bbb", MEMCACHE.get("ta:aaa"))
|
assert_equal("bbb", MEMCACHE.get("ta:aaa"))
|
||||||
ta.destroy
|
ta.destroy
|
||||||
assert_nil(MEMCACHE.get("ta:aaa"))
|
assert_nil(MEMCACHE.get("ta:aaa"))
|
||||||
@@ -42,7 +42,7 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
post2 = Factory.create(:post, :tag_string => "ccc ddd")
|
post2 = Factory.create(:post, :tag_string => "ccc ddd")
|
||||||
assert_equal("aaa bbb", post1.tag_string)
|
assert_equal("aaa bbb", post1.tag_string)
|
||||||
assert_equal("ccc ddd", post2.tag_string)
|
assert_equal("ccc ddd", post2.tag_string)
|
||||||
ta = Factory.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "ccc")
|
ta = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "ccc")
|
||||||
post1.reload
|
post1.reload
|
||||||
post2.reload
|
post2.reload
|
||||||
assert_equal("ccc bbb", post1.tag_string)
|
assert_equal("ccc bbb", post1.tag_string)
|
||||||
@@ -50,7 +50,7 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "not validate for transitive relations" do
|
should "not validate for transitive relations" do
|
||||||
ta1 = Factory.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ta1 = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
assert_difference("TagAlias.count", 0) do
|
assert_difference("TagAlias.count", 0) do
|
||||||
ta3 = Factory.build(:tag_alias, :antecedent_name => "bbb", :consequent_name => "ddd")
|
ta3 = Factory.build(:tag_alias, :antecedent_name => "bbb", :consequent_name => "ddd")
|
||||||
ta3.save
|
ta3.save
|
||||||
@@ -60,15 +60,15 @@ class TagAliasTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "record the alias's creator in the tag history" do
|
should "record the alias's creator in the tag history" do
|
||||||
user = Factory.create(:user)
|
uploader = Factory.create(:user)
|
||||||
p1 = nil
|
post = nil
|
||||||
CurrentUser.scoped(user, "127.0.0.1") do
|
CurrentUser.scoped(uploader, "127.0.0.1") do
|
||||||
p1 = Factory.create(:post, :tag_string => "aaa bbb ccc")
|
post = Factory.create(:post, :tag_string => "aaa bbb ccc")
|
||||||
end
|
end
|
||||||
ta1 = Factory.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "xxx")
|
tag_alias = FactoryGirl.create(:tag_alias, :antecedent_name => "aaa", :consequent_name => "xxx")
|
||||||
p1.reload
|
post.reload
|
||||||
assert_not_equal(ta1.creator_id, p1.uploader_id)
|
assert_not_equal(tag_alias.creator_id, post.uploader_id)
|
||||||
assert_equal(ta1.creator_id, p1.versions.last.updater_id)
|
assert_equal(tag_alias.creator_id, post.versions.last.updater_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "populate the creator information" do
|
should "populate the creator information" do
|
||||||
ti = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ti = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
assert_equal(CurrentUser.user.id, ti.creator_id)
|
assert_equal(CurrentUser.user.id, ti.creator_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
should "not validate when a circular relation is created" do
|
should "not validate when a circular relation is created" do
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ti1 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
ti2 = Factory.build(:tag_implication, :antecedent_name => "bbb", :consequent_name => "aaa")
|
ti2 = Factory.build(:tag_implication, :antecedent_name => "bbb", :consequent_name => "aaa")
|
||||||
ti2.save
|
ti2.save
|
||||||
assert(ti2.errors.any?, "Tag implication should not have validated.")
|
assert(ti2.errors.any?, "Tag implication should not have validated.")
|
||||||
@@ -29,34 +29,18 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "not allow for duplicates" do
|
should "not allow for duplicates" do
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ti1 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
ti2 = Factory.build(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ti2 = Factory.build(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
ti2.save
|
ti2.save
|
||||||
assert(ti2.errors.any?, "Tag implication should not have validated.")
|
assert(ti2.errors.any?, "Tag implication should not have validated.")
|
||||||
assert_equal("Antecedent name has already been taken", ti2.errors.full_messages.join(""))
|
assert_equal("Antecedent name has already been taken", ti2.errors.full_messages.join(""))
|
||||||
end
|
end
|
||||||
|
|
||||||
should "clear the cache upon saving" do
|
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
|
||||||
assert_equal(["bbb"], ti1.descendant_names_array)
|
|
||||||
assert_equal(["bbb"], MEMCACHE.get("ti:aaa"))
|
|
||||||
ti1.update_attributes(
|
|
||||||
:consequent_name => "ccc"
|
|
||||||
)
|
|
||||||
assert_equal(["ccc"], MEMCACHE.get("ti:aaa"))
|
|
||||||
end
|
|
||||||
|
|
||||||
should "clear the cache upon destruction" do
|
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
|
||||||
ti1.destroy
|
|
||||||
assert_nil(MEMCACHE.get("ti:aaa"))
|
|
||||||
end
|
|
||||||
|
|
||||||
should "calculate all its descendants" do
|
should "calculate all its descendants" do
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "bbb", :consequent_name => "ccc")
|
ti1 = FactoryGirl.create(:tag_implication, :antecedent_name => "bbb", :consequent_name => "ccc")
|
||||||
assert_equal("ccc", ti1.descendant_names)
|
assert_equal("ccc", ti1.descendant_names)
|
||||||
assert_equal(["ccc"], ti1.descendant_names_array)
|
assert_equal(["ccc"], ti1.descendant_names_array)
|
||||||
ti2 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ti2 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
assert_equal("bbb ccc", ti2.descendant_names)
|
assert_equal("bbb ccc", ti2.descendant_names)
|
||||||
assert_equal(["bbb", "ccc"], ti2.descendant_names_array)
|
assert_equal(["bbb", "ccc"], ti2.descendant_names_array)
|
||||||
ti1.reload
|
ti1.reload
|
||||||
@@ -64,15 +48,9 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
assert_equal(["ccc"], ti1.descendant_names_array)
|
assert_equal(["ccc"], ti1.descendant_names_array)
|
||||||
end
|
end
|
||||||
|
|
||||||
should "cache its descendants" do
|
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
|
||||||
assert_equal(["bbb"], ti1.descendant_names_array)
|
|
||||||
assert_equal(["bbb"], MEMCACHE.get("ti:aaa"))
|
|
||||||
end
|
|
||||||
|
|
||||||
should "update its descendants on save" do
|
should "update its descendants on save" do
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ti1 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
ti2 = Factory.create(:tag_implication, :antecedent_name => "ccc", :consequent_name => "ddd")
|
ti2 = FactoryGirl.create(:tag_implication, :antecedent_name => "ccc", :consequent_name => "ddd")
|
||||||
ti2.update_attributes(
|
ti2.update_attributes(
|
||||||
:antecedent_name => "bbb"
|
:antecedent_name => "bbb"
|
||||||
)
|
)
|
||||||
@@ -83,10 +61,10 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
should "update the decendants for its parent on save" do
|
should "update the decendants for its parent on save" do
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
ti1 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "bbb")
|
||||||
ti2 = Factory.create(:tag_implication, :antecedent_name => "bbb", :consequent_name => "ccc")
|
ti2 = FactoryGirl.create(:tag_implication, :antecedent_name => "bbb", :consequent_name => "ccc")
|
||||||
ti3 = Factory.create(:tag_implication, :antecedent_name => "ccc", :consequent_name => "ddd")
|
ti3 = FactoryGirl.create(:tag_implication, :antecedent_name => "ccc", :consequent_name => "ddd")
|
||||||
ti4 = Factory.create(:tag_implication, :antecedent_name => "ccc", :consequent_name => "eee")
|
ti4 = FactoryGirl.create(:tag_implication, :antecedent_name => "ccc", :consequent_name => "eee")
|
||||||
ti1.reload
|
ti1.reload
|
||||||
ti2.reload
|
ti2.reload
|
||||||
ti3.reload
|
ti3.reload
|
||||||
@@ -99,8 +77,8 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
should "update any affected post upon save" do
|
should "update any affected post upon save" do
|
||||||
p1 = Factory.create(:post, :tag_string => "aaa bbb ccc")
|
p1 = Factory.create(:post, :tag_string => "aaa bbb ccc")
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "xxx")
|
ti1 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "xxx")
|
||||||
ti2 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "yyy")
|
ti2 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "yyy")
|
||||||
p1.reload
|
p1.reload
|
||||||
assert_equal("aaa yyy xxx bbb ccc", p1.tag_string)
|
assert_equal("aaa yyy xxx bbb ccc", p1.tag_string)
|
||||||
end
|
end
|
||||||
@@ -111,7 +89,7 @@ class TagImplicationTest < ActiveSupport::TestCase
|
|||||||
CurrentUser.scoped(user, "127.0.0.1") do
|
CurrentUser.scoped(user, "127.0.0.1") do
|
||||||
p1 = Factory.create(:post, :tag_string => "aaa bbb ccc")
|
p1 = Factory.create(:post, :tag_string => "aaa bbb ccc")
|
||||||
end
|
end
|
||||||
ti1 = Factory.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "xxx")
|
ti1 = FactoryGirl.create(:tag_implication, :antecedent_name => "aaa", :consequent_name => "xxx")
|
||||||
p1.reload
|
p1.reload
|
||||||
assert_not_equal(ti1.creator_id, p1.uploader_id)
|
assert_not_equal(ti1.creator_id, p1.uploader_id)
|
||||||
assert_equal(ti1.creator_id, p1.versions.last.updater_id)
|
assert_equal(ti1.creator_id, p1.versions.last.updater_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user