diff --git a/app/assets/stylesheets/specific/users.css.scss b/app/assets/stylesheets/specific/users.css.scss
index 8a3e0d519..5a82d54bf 100644
--- a/app/assets/stylesheets/specific/users.css.scss
+++ b/app/assets/stylesheets/specific/users.css.scss
@@ -2,6 +2,28 @@
div#c-users {
div#a-show {
+ div.grid {
+ div.col {
+ float: left;
+ width: 50%;
+ }
+
+ div.box {
+ clear: both;
+ margin-bottom: 2em;
+ }
+
+ /* clearfix hacks */
+ div.box:before, div.box:after {
+ content: "";
+ display: table;
+ }
+
+ div.box:after {
+ clear: both;
+ }
+ }
+
dl {
dt {
width: 12em;
diff --git a/app/models/tag_subscription.rb b/app/models/tag_subscription.rb
index 2cd211256..270b3774a 100644
--- a/app/models/tag_subscription.rb
+++ b/app/models/tag_subscription.rb
@@ -6,6 +6,7 @@ class TagSubscription < ActiveRecord::Base
before_save :limit_tag_count
attr_accessible :name, :tag_query, :post_ids, :is_public, :is_visible_on_profile
validates_presence_of :name, :tag_query, :is_public, :creator_id
+ validate :creator_can_create_subscriptions
def normalize_name
self.name = name.gsub(/\W/, "_")
@@ -18,6 +19,15 @@ class TagSubscription < ActiveRecord::Base
def initialize_post_ids
process
end
+
+ def creator_can_create_subscriptions
+ if TagSubscription.owned_by(creator).count >= Danbooru.config.max_tag_subscriptions
+ self.errors.add(:creator, "can subscribe up to #{Danbooru.config.max_tag_subscriptions} tags")
+ return false
+ else
+ return true
+ end
+ end
def tag_query_array
Tag.scan_query(tag_query)
@@ -94,10 +104,10 @@ class TagSubscription < ActiveRecord::Base
end
def self.find_post_ids(user_id, name = nil, limit = Danbooru.config.tag_subscription_post_limit)
- relation = where(["creator_id = ?", user_id])
+ relation = where("creator_id = ?", user_id)
if name
- relation = relation.where(["name ILIKE ? ESCAPE E'\\\\'", name.to_escaped_for_sql_like])
+ relation = relation.where("name ILIKE ? ESCAPE E'\\\\'", name.to_escaped_for_sql_like)
end
relation.each do |tag_sub|
diff --git a/app/presenters/user_presenter.rb b/app/presenters/user_presenter.rb
index 038676ed1..da920b395 100644
--- a/app/presenters/user_presenter.rb
+++ b/app/presenters/user_presenter.rb
@@ -25,10 +25,16 @@ class UserPresenter
end
end
- def tag_subscriptions(template)
- user.subscriptions.map do |subscription|
- template.link_to(subscription.name, template.tag_subscription_path(subscription))
- end.join("; ")
+ def tag_subscriptions
+ if CurrentUser.user.id == user.id
+ user.subscriptions
+ else
+ user.subscriptions.select {|x| x.is_public?}
+ end
+ end
+
+ def posts_for_subscription(subscription)
+ Post.where("id in (?)", subscription.post_id_array.slice(0, 6).map(&:to_i))
end
def upload_limit
@@ -57,39 +63,55 @@ class UserPresenter
return string
end
- def uploads(template)
+ def uploads
+ @uploads ||= Post.where("uploader_id = ?", user.id).order("id desc").limit(6)
+ end
+
+ def has_uploads?
+ user.post_upload_count > 0
+ end
+
+ def favorites
+ @favorites ||= user.favorites.limit(6).includes(:post).map(&:post)
+ end
+
+ def has_favorites?
+ user.favorite_count > 0
+ end
+
+ def upload_count(template)
template.link_to(user.post_upload_count, template.posts_path(:tags => "user:#{user.name}"))
end
- def deleted_uploads(template)
+ def deleted_upload_count(template)
template.link_to(Post.for_user(user.id).deleted.count, template.posts_path(:tags => "status:deleted user:#{user.name}"))
end
- def favorites(template)
+ def favorite_count(template)
template.link_to(user.favorite_count, template.posts_path(:tags => "fav:#{user.name}"))
end
- def comments(template)
+ def comment_count(template)
template.link_to(Comment.for_creator(user.id).count, template.comments_path(:search => {:creator_id => user.id}))
end
- def post_versions(template)
+ def post_version_count(template)
template.link_to(user.post_update_count, template.post_versions_path(:search => {:updater_id => user.id}))
end
- def note_versions(template)
+ def note_version_count(template)
template.link_to(user.note_update_count, template.note_versions_path(:search => {:updater_id => user.id}))
end
- def wiki_page_versions(template)
+ def wiki_page_version_count(template)
template.link_to(WikiPageVersion.for_user(user.id).count, template.wiki_page_versions_path(:search => {:updater_id => user.id}))
end
- def forum_posts(template)
+ def forum_post_count(template)
template.link_to(ForumPost.for_user(user.id).count, template.forum_posts_path(:search => {:creator_id => user.id}))
end
- def pool_versions(template)
+ def pool_version_count(template)
template.link_to(PoolVersion.for_user(user.id).count, template.pool_versions_path(:search => {:updater_id => user.id}))
end
@@ -101,7 +123,7 @@ class UserPresenter
end
end
- def approvals(template)
+ def approval_count(template)
template.link_to(Post.where("approver_id = ?", user.id).count, template.posts_path(:tags => "approver:#{user.name}"))
end
@@ -113,15 +135,17 @@ class UserPresenter
template.link_to("positive:#{positive} neutral:#{neutral} negative:#{negative}", template.user_feedbacks_path(:search => {:user_id => user.id}))
end
- def subscriptions(template)
- if user.subscriptions.any?
- str = user.subscriptions.map do |subscription|
- template.link_to(subscription.name, template.posts_path(:tags => "sub:#{user.name}:#{subscription.name}"))
- end.join(", ")
- str += " [" + template.link_to("edit", template.tag_subscriptions_path) + "]"
- str.html_safe
- else
- "None"
- end
+ def subscriptions
+ user.subscriptions
+ #
+ # if user.subscriptions.any?
+ # str = user.subscriptions.map do |subscription|
+ # template.link_to(subscription.name, template.posts_path(:tags => "sub:#{user.name}:#{subscription.name}"))
+ # end.join(", ")
+ # str += " [" + template.link_to("edit", template.tag_subscriptions_path) + "]"
+ # str.html_safe
+ # else
+ # "None"
+ # end
end
end
diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb
index eefcd18d7..8c74db2ae 100644
--- a/app/views/posts/index.html.erb
+++ b/app/views/posts/index.html.erb
@@ -11,7 +11,7 @@
Tags
<%= @post_set.presenter.tag_list_html(self) %>
-
+
<%= render "posts/partials/index/blacklist" %>
<%= render "posts/partials/index/related" %>
diff --git a/app/views/posts/partials/index/_related.html.erb b/app/views/posts/partials/index/_related.html.erb
index 0d9083206..76aeb1d25 100644
--- a/app/views/posts/partials/index/_related.html.erb
+++ b/app/views/posts/partials/index/_related.html.erb
@@ -1,8 +1,12 @@
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index f1e99af1a..2f80b6a7e 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -2,60 +2,106 @@
<%= @presenter.name %>
-
- - Join Date
- - <%= @presenter.join_date %>
+
+
+
+
<%= link_to "Uploads", posts_path(:tags => "user:#{@user.name}") %>
+ <% if @presenter.has_uploads? %>
+
+ <% @presenter.uploads.each do |post| %>
+ <%= PostPresenter.preview(post) %>
+ <% end %>
+
+ <% else %>
+
None
+ <% end %>
+
+
+
+
<%= link_to "Favorites", posts_path(:tags => "fav:#{@user.name}") %>
+ <% if @presenter.has_favorites? %>
+
+ <% @presenter.favorites.each do |post| %>
+ <%= PostPresenter.preview(post) %>
+ <% end %>
+
+ <% else %>
+
None
+ <% end %>
+
+
+
+
Subscriptions
+ <% @presenter.subscriptions.each do |subscription| %>
+
+
<%= link_to subscription.name, posts_path(:tags => "sub:#{@user.name}:#{subscription.name}") %>
+
+
+ <% @presenter.posts_for_subscription(subscription).each do |post| %>
+ <%= PostPresenter.preview(post) %>
+ <% end %>
+
+
+
+ <% end %>
+
+
-
- Inviter
-
- <%= @presenter.inviter(self) %>
-
-
- Level
-
- <%= @presenter.level %>
-
- <% if @user.is_banned? %>
-
- Ban reason
-
- <%= @presenter.ban_reason %>
- <% end %>
-
-
- Upload Limit
-
- <%= @presenter.upload_limit %>
+
+
Statistics
+
+ - Join Date
+ - <%= @presenter.join_date %>
- - Uploads
- - <%= @presenter.uploads(self) %>
+ - Inviter
+ - <%= @presenter.inviter(self) %>
- - Deleted Uploads
- - <%= @presenter.deleted_uploads(self) %>
+ - Level
+ - <%= @presenter.level %>
- - Favorites
- - <%= @presenter.favorites(self) %>
+ <% if @user.is_banned? %>
+ - Ban reason
+ - <%= @presenter.ban_reason %>
+ <% end %>
- - Subscriptions
- - <%= @presenter.subscriptions(self) %>
+ - Upload Limit
+ - <%= @presenter.upload_limit %>
- - Post Changes
- - <%= @presenter.post_versions(self) %>
+ - Uploads
+ - <%= @presenter.upload_count(self) %>
- - Note Changes
- - <%= @presenter.note_versions(self) %>
+ - Deleted Uploads
+ - <%= @presenter.deleted_upload_count(self) %>
- - Wiki Page Changes
- - <%= @presenter.wiki_page_versions(self) %>
+ - Favorites
+ - <%= @presenter.favorite_count(self) %>
- - Pool Changes
- - <%= @presenter.pool_versions(self) %>
+ - Post Changes
+ - <%= @presenter.post_version_count(self) %>
- - Forum Posts
- - <%= @presenter.forum_posts(self) %>
+ - Note Changes
+ - <%= @presenter.note_version_count(self) %>
- - Approvals
- - <%= @presenter.approvals(self) %>
-
- - Comments
- - <%= @presenter.comments(self) %>
+ - Wiki Page Changes
+ - <%= @presenter.wiki_page_version_count(self) %>
- - Feedback
- - <%= @presenter.feedbacks(self) %>
-
+
- Pool Changes
+
- <%= @presenter.pool_version_count(self) %>
+
+
- Forum Posts
+
- <%= @presenter.forum_post_count(self) %>
+
+
- Approvals
+
- <%= @presenter.approval_count(self) %>
+
+
- Comments
+
- <%= @presenter.comment_count(self) %>
+
+
- Feedback
+
- <%= @presenter.feedbacks(self) %>
+
+
+
diff --git a/db/migrate/20130221214811_add_index_updated_at_on_pool_versions.rb b/db/migrate/20130221214811_add_index_updated_at_on_pool_versions.rb
index 4d3dff3a2..01bca170e 100644
--- a/db/migrate/20130221214811_add_index_updated_at_on_pool_versions.rb
+++ b/db/migrate/20130221214811_add_index_updated_at_on_pool_versions.rb
@@ -1,11 +1,11 @@
class AddIndexUpdatedAtOnPoolVersions < ActiveRecord::Migration
def up
execute "set statement_timeout = 0"
- add_index :post_versions, :updated_at
+ add_index :pool_versions, :updated_at
end
def down
execute "set statement_timeout = 0"
- remove_index :post_versions, :updated_at
+ remove_index :pool_versions, :updated_at
end
end
diff --git a/db/structure.sql b/db/structure.sql
index 183187111..32f8a2cb7 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -5647,6 +5647,13 @@ CREATE INDEX index_notes_on_post_id ON notes USING btree (post_id);
CREATE INDEX index_pool_versions_on_pool_id ON pool_versions USING btree (pool_id);
+--
+-- Name: index_pool_versions_on_updated_at; Type: INDEX; Schema: public; Owner: -; Tablespace:
+--
+
+CREATE INDEX index_pool_versions_on_updated_at ON pool_versions USING btree (updated_at);
+
+
--
-- Name: index_pool_versions_on_updater_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@@ -6198,4 +6205,6 @@ INSERT INTO schema_migrations (version) VALUES ('20130219184743');
INSERT INTO schema_migrations (version) VALUES ('20130221032344');
-INSERT INTO schema_migrations (version) VALUES ('20130221035518');
\ No newline at end of file
+INSERT INTO schema_migrations (version) VALUES ('20130221035518');
+
+INSERT INTO schema_migrations (version) VALUES ('20130221214811');
\ No newline at end of file
diff --git a/test/unit/tag_subscription_test.rb b/test/unit/tag_subscription_test.rb
index 9ebee0de8..939718e33 100644
--- a/test/unit/tag_subscription_test.rb
+++ b/test/unit/tag_subscription_test.rb
@@ -14,6 +14,19 @@ class TagSubscriptionTest < ActiveSupport::TestCase
end
context "A tag subscription" do
+ context "for a user with too many subscriptions" do
+ setup do
+ Danbooru.config.stubs(:max_tag_subscriptions).returns(0)
+ @user = FactoryGirl.create(:user)
+ end
+
+ should "fail" do
+ sub = FactoryGirl.build(:tag_subscription, :tag_query => "aaa bbb", :creator => @user, :name => "zzz")
+ sub.save
+ assert_equal(["Creator can subscribe up to 0 tags"], sub.errors.full_messages)
+ end
+ end
+
should "find the union of all posts for each tag in its tag query" do
posts = []
user = FactoryGirl.create(:user)
@@ -21,10 +34,12 @@ class TagSubscriptionTest < ActiveSupport::TestCase
posts << FactoryGirl.create(:post, :tag_string => "bbb")
posts << FactoryGirl.create(:post, :tag_string => "ccc")
posts << FactoryGirl.create(:post, :tag_string => "ddd")
- sub_1 = FactoryGirl.create(:tag_subscription, :tag_query => "aaa bbb", :creator => user, :name => "zzz")
- sub_2 = FactoryGirl.create(:tag_subscription, :tag_query => "ccc", :creator => user, :name => "yyy")
- assert_equal([posts[1].id, posts[0].id], TagSubscription.find_posts(user.id, "zzz").map(&:id))
- assert_equal([posts[2].id, posts[1].id, posts[0].id], TagSubscription.find_posts(user.id).map(&:id))
+ CurrentUser.scoped(user, "127.0.0.1") do
+ sub_1 = FactoryGirl.create(:tag_subscription, :tag_query => "aaa bbb", :name => "zzz")
+ sub_2 = FactoryGirl.create(:tag_subscription, :tag_query => "ccc", :name => "yyy")
+ assert_equal([posts[1].id, posts[0].id], TagSubscription.find_posts(user.id, "zzz").map(&:id))
+ assert_equal([posts[2].id, posts[1].id, posts[0].id], TagSubscription.find_posts(user.id).map(&:id))
+ end
end
should "cache its tag query results" do
@@ -33,26 +48,30 @@ class TagSubscriptionTest < ActiveSupport::TestCase
posts << FactoryGirl.create(:post, :tag_string => "aaa")
posts << FactoryGirl.create(:post, :tag_string => "bbb")
posts << FactoryGirl.create(:post, :tag_string => "ccc")
- sub = FactoryGirl.create(:tag_subscription, :tag_query => "aaa bbb", :creator => user, :name => "zzz")
- assert_equal("#{posts[1].id},#{posts[0].id}", sub.post_ids)
+ CurrentUser.scoped(user, "127.0.0.1") do
+ sub = FactoryGirl.create(:tag_subscription, :tag_query => "aaa bbb", :name => "zzz")
+ assert_equal("#{posts[1].id},#{posts[0].id}", sub.post_ids)
+ end
end
should "find posts based on its cached post ids" do
user = FactoryGirl.create(:user)
- subs = []
- subs << FactoryGirl.create(:tag_subscription, :tag_query => "aaa", :creator => user, :name => "zzz")
- subs << FactoryGirl.create(:tag_subscription, :tag_query => "bbb", :creator => user, :name => "yyy")
- assert_equal([], TagSubscription.find_posts(user.id))
- assert_equal([], TagSubscription.find_posts(user.id, "zzz"))
- assert_equal([], TagSubscription.find_posts(user.id, "yyy"))
- posts = []
- posts << FactoryGirl.create(:post, :tag_string => "aaa")
- posts << FactoryGirl.create(:post, :tag_string => "bbb")
- posts << FactoryGirl.create(:post, :tag_string => "ccc")
- subs.each {|x| x.process; x.save}
- assert_equal([posts[1].id, posts[0].id], TagSubscription.find_posts(user.id).map(&:id))
- assert_equal([posts[0].id], TagSubscription.find_posts(user.id, "zzz").map(&:id))
- assert_equal([posts[1].id], TagSubscription.find_posts(user.id, "yyy").map(&:id))
+ CurrentUser.scoped(user, "127.0.0.1") do
+ subs = []
+ subs << FactoryGirl.create(:tag_subscription, :tag_query => "aaa", :name => "zzz")
+ subs << FactoryGirl.create(:tag_subscription, :tag_query => "bbb", :name => "yyy")
+ assert_equal([], TagSubscription.find_posts(user.id))
+ assert_equal([], TagSubscription.find_posts(user.id, "zzz"))
+ assert_equal([], TagSubscription.find_posts(user.id, "yyy"))
+ posts = []
+ posts << FactoryGirl.create(:post, :tag_string => "aaa")
+ posts << FactoryGirl.create(:post, :tag_string => "bbb")
+ posts << FactoryGirl.create(:post, :tag_string => "ccc")
+ subs.each {|x| x.process; x.save}
+ assert_equal([posts[1].id, posts[0].id], TagSubscription.find_posts(user.id).map(&:id))
+ assert_equal([posts[0].id], TagSubscription.find_posts(user.id, "zzz").map(&:id))
+ assert_equal([posts[1].id], TagSubscription.find_posts(user.id, "yyy").map(&:id))
+ end
end
end
@@ -66,8 +85,12 @@ class TagSubscriptionTest < ActiveSupport::TestCase
posts << FactoryGirl.create(:post, :tag_string => "bbb")
posts << FactoryGirl.create(:post, :tag_string => "ccc")
subscriptions = []
- subscriptions << FactoryGirl.create(:tag_subscription, :tag_query => "aaa", :creator => users[0])
- subscriptions << FactoryGirl.create(:tag_subscription, :tag_query => "bbb", :creator => users[1])
+ CurrentUser.scoped(users[0], "127.0.0.1") do
+ subscriptions << FactoryGirl.create(:tag_subscription, :tag_query => "aaa")
+ end
+ CurrentUser.scoped(users[1], "127.0.0.1") do
+ subscriptions << FactoryGirl.create(:tag_subscription, :tag_query => "bbb")
+ end
TagSubscription.process_all
subscriptions.each {|x| x.reload}
assert_equal("#{posts[0].id}", subscriptions[0].post_ids)