diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index 3d7b07633..098fea73d 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -334,6 +334,7 @@ div#page { width: 75%; float: left; margin-left: 2em; + overflow: hidden; } } @@ -714,6 +715,9 @@ div#c-posts { } } +div#c-explore-posts { +} + /*** Post Histories ***/ div.post_histories { diff --git a/app/controllers/explore/posts_controller.rb b/app/controllers/explore/posts_controller.rb new file mode 100644 index 000000000..324e013cd --- /dev/null +++ b/app/controllers/explore/posts_controller.rb @@ -0,0 +1,11 @@ +module Explore + class PostsController < ApplicationController + respond_to :html, :xml, :json + + def popular + @post_set = PostSets::Popular.new(params[:date], params[:scale]) + @posts = @post_set.posts + respond_with(@posts) + end + end +end diff --git a/app/logical/pixiv_proxy.rb b/app/logical/pixiv_proxy.rb index febb33296..5db0dcdc9 100644 --- a/app/logical/pixiv_proxy.rb +++ b/app/logical/pixiv_proxy.rb @@ -4,7 +4,7 @@ class PixivProxy end def self.get(url) - if url =~ /\/(\d+)(_m)?\.(jpg|jpeg|png|gif)/i + if url =~ /\/(\d+)(_m|_p\d+)?\.(jpg|jpeg|png|gif)/i url = "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=#{$1}" get_single(url) elsif url =~ /member_illust\.php/ && url =~ /illust_id=/ diff --git a/app/logical/post_sets/artist.rb b/app/logical/post_sets/artist.rb index e3cc9371f..d7dbb4903 100644 --- a/app/logical/post_sets/artist.rb +++ b/app/logical/post_sets/artist.rb @@ -3,7 +3,7 @@ module PostSets attr_reader :artist def initialize(artist) - super(:tags => artist.name) + super(artist.name) @artist = artist end diff --git a/app/logical/post_sets/base.rb b/app/logical/post_sets/base.rb index cef6b5b8e..dcd62826e 100644 --- a/app/logical/post_sets/base.rb +++ b/app/logical/post_sets/base.rb @@ -13,6 +13,7 @@ module PostSets end def artist + nil end def is_single_tag? diff --git a/app/logical/post_sets/popular.rb b/app/logical/post_sets/popular.rb new file mode 100644 index 000000000..30550cd6c --- /dev/null +++ b/app/logical/post_sets/popular.rb @@ -0,0 +1,48 @@ +module PostSets + class Popular < Base + attr_reader :date, :scale + + def initialize(date, scale) + @date = date.blank? ? Date.today : date.to_date + @scale = scale + end + + def posts + ::Post.where("created_at between ? and ?", min_date, max_date + 1).order("score desc").limit(limit) + end + + def limit + 25 + end + + def min_date + case scale + when "week" + date.beginning_of_week + + when "month" + date.beginning_of_month + + else + date + end + end + + def max_date + case scale + when "week" + date.end_of_week + + when "month" + date.end_of_month + + else + date + end + end + + def presenter + ::PostSetPresenters::Popular.new(self) + end + end +end diff --git a/app/models/comment.rb b/app/models/comment.rb index ef2bafdd5..2d2658faa 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -13,6 +13,7 @@ class Comment < ActiveRecord::Base scope :body_matches, lambda {|query| where("body_index @@ plainto_tsquery(?)", query).order("comments.id DESC")} scope :hidden, lambda {|user| where("score < ?", user.comment_threshold)} scope :post_tag_match, lambda {|query| joins(:post).where("posts.tag_index @@ to_tsquery('danbooru', ?)", query)} + scope :for_user, lambda {|user_id| where("creator_id = ?", user_id)} search_methods :body_matches, :post_tag_match diff --git a/app/models/favorite.rb b/app/models/favorite.rb index c267ce368..4798cb231 100644 --- a/app/models/favorite.rb +++ b/app/models/favorite.rb @@ -1,4 +1,4 @@ class Favorite < ActiveRecord::Base belongs_to :post - scope :for_user, lambda {|user_id| where("user_id = ?", user_id)} + scope :for_user, lambda {|user_id| where("user_id = #{user_id}")} end diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb index 9002ec4aa..f82238bba 100644 --- a/app/models/forum_post.rb +++ b/app/models/forum_post.rb @@ -8,6 +8,7 @@ class ForumPost < ActiveRecord::Base validates_presence_of :body, :creator_id validate :validate_topic_is_unlocked scope :body_matches, lambda {|body| where(["text_index @@ plainto_tsquery(?)", body])} + scope :for_user, lambda {|user_id| where("creator_id = ?", user_id)} search_methods :body_matches def self.new_reply(params) diff --git a/app/models/note_version.rb b/app/models/note_version.rb index c08d8dfb3..96076ac5e 100644 --- a/app/models/note_version.rb +++ b/app/models/note_version.rb @@ -1,6 +1,7 @@ class NoteVersion < ActiveRecord::Base before_validation :initialize_updater belongs_to :updater, :class_name => "User" + scope :for_user, lambda {|user_id| where("updater_id = ?", user_id)} def initialize_updater self.updater_id = CurrentUser.id diff --git a/app/models/pool_version.rb b/app/models/pool_version.rb index ef8712566..c85cf236e 100644 --- a/app/models/pool_version.rb +++ b/app/models/pool_version.rb @@ -5,6 +5,7 @@ class PoolVersion < ActiveRecord::Base belongs_to :pool belongs_to :updater, :class_name => "User" before_validation :initialize_updater + scope :for_user, lambda {|user_id| where("updater_id = ?", user_id)} def initialize_updater self.updater_id = CurrentUser.id diff --git a/app/models/post.rb b/app/models/post.rb index 78610f88e..d9e82f357 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -586,6 +586,10 @@ class Post < ActiveRecord::Base relation = relation.where("posts.rating <> 'e'") end + if q[:order] == "rank" + relation = relation.where("p.score > 0 and p.created_at >= ?", 0, 3.days.ago) + end + case q[:order] when "id", "id_asc" relation = relation.order("posts.id") @@ -619,6 +623,9 @@ class Post < ActiveRecord::Base when "filesize_asc" relation = relation.order("posts.file_size") + when "rank" + sql << " ORDER BY log(3, p.score) + (extract(epoch from p.created_at) - extract(epoch from timestamp '2005-05-24')) / 45000 DESC" + else relation = relation.order("posts.id DESC") end diff --git a/app/models/post_version.rb b/app/models/post_version.rb index 4c2ab2fac..0a99660fb 100644 --- a/app/models/post_version.rb +++ b/app/models/post_version.rb @@ -2,6 +2,7 @@ class PostVersion < ActiveRecord::Base belongs_to :post belongs_to :updater, :class_name => "User" before_validation :initialize_updater + scope :for_user, lambda {|user_id| where("updater_id = ?", user_id)} def self.create_from_post(post) if post.created_at == post.updated_at diff --git a/app/models/user_feedback.rb b/app/models/user_feedback.rb index e10cba48a..ada74f13b 100644 --- a/app/models/user_feedback.rb +++ b/app/models/user_feedback.rb @@ -9,6 +9,7 @@ class UserFeedback < ActiveRecord::Base scope :positive, where("category = ?", "positive") scope :neutral, where("category = ?", "neutral") scope :negative, where("category = ?", "negative") + scope :for_user, lambda {|user_id| where("user_id = ?", user_id)} def initialize_creator self.creator_id = CurrentUser.id diff --git a/app/models/wiki_page_version.rb b/app/models/wiki_page_version.rb index 00a5cb728..75e5f01fa 100644 --- a/app/models/wiki_page_version.rb +++ b/app/models/wiki_page_version.rb @@ -1,6 +1,7 @@ class WikiPageVersion < ActiveRecord::Base belongs_to :wiki_page belongs_to :updater, :class_name => "User" + scope :for_user, lambda {|user_id| where("updater_id = ?", user_id)} def updater_name User.id_to_name(updater_id) diff --git a/app/presenters/post_set_presenters/base.rb b/app/presenters/post_set_presenters/base.rb new file mode 100644 index 000000000..b2b93dcf6 --- /dev/null +++ b/app/presenters/post_set_presenters/base.rb @@ -0,0 +1,21 @@ +module PostSetPresenters + class Base + def posts + raise NotImplementedError + end + + def post_previews_html(template) + html = "" + + if posts.empty? + return template.render(:partial => "post_sets/blank") + end + + posts.each do |post| + html << PostPresenter.preview(post) + end + + html.html_safe + end + end +end diff --git a/app/presenters/post_set_presenters/favorite.rb b/app/presenters/post_set_presenters/favorite.rb index 1b7fb7b5e..b9a97fd4f 100644 --- a/app/presenters/post_set_presenters/favorite.rb +++ b/app/presenters/post_set_presenters/favorite.rb @@ -1,7 +1,7 @@ module PostSetPresenters - class Favorite + class Favorite < Base attr_accessor :favorite_set, :tag_set_presenter - delegate :favorites, :posts, :to => :favorite_set + delegate :favorites, :to => :favorite_set def initialize(favorite_set) @favorite_set = favorite_set @@ -15,19 +15,9 @@ module PostSetPresenters def tag_list_html(template) tag_set_presenter.tag_list_html(template) end - - def post_previews_html(template) - html = "" - - if favorites.empty? - return template.render(:partial => "post_sets/blank") - end - - favorites.each do |favorite| - html << PostPresenter.preview(favorite.post) - end - - html.html_safe + + def posts + favorites.map(&:post) end end end diff --git a/app/presenters/post_set_presenters/pool.rb b/app/presenters/post_set_presenters/pool.rb index fbb805748..c16270f80 100644 --- a/app/presenters/post_set_presenters/pool.rb +++ b/app/presenters/post_set_presenters/pool.rb @@ -1,12 +1,13 @@ module PostSetPresenters - class Pool - attr_reader :tag_set_presenter, :pool_set + class Pool < Base + attr_reader :tag_set_presenter, :post_set + delegate :posts, :to => :post_set - def initialize(pool_set) - @pool_set = pool_set + def initialize(post_set) + @post_set = post_set @tag_set_presenter = TagSetPresenter.new( RelatedTagCalculator.calculate_from_sample_to_array( - pool_set.tag_string + post_set.tag_string ).map {|x| x[0]} ) end @@ -14,19 +15,5 @@ module PostSetPresenters def tag_list_html(template) tag_set_presenter.tag_list_html(template) end - - def post_previews_html(template) - html = "" - - if pool_set.posts.empty? - return template.render(:partial => "post_sets/blank") - end - - pool_set.posts.each do |post| - html << PostPresenter.preview(post) - end - - html.html_safe - end end end diff --git a/app/presenters/post_set_presenters/popular.rb b/app/presenters/post_set_presenters/popular.rb new file mode 100644 index 000000000..0d58f5e19 --- /dev/null +++ b/app/presenters/post_set_presenters/popular.rb @@ -0,0 +1,34 @@ +module PostSetPresenters + class Popular < Base + attr_accessor :post_set, :tag_set_presenter + delegate :posts, :date, :to => :post_set + + def initialize(post_set) + @post_set = post_set + end + + def prev_day + date - 1 + end + + def next_day + date + 1 + end + + def prev_week + date - 7 + end + + def next_week + date + 7 + end + + def prev_month + 1.month.ago(date) + end + + def next_month + 1.month.since(date) + end + end +end diff --git a/app/presenters/post_set_presenters/post.rb b/app/presenters/post_set_presenters/post.rb index 07cd2e9bd..1a5b0351c 100644 --- a/app/presenters/post_set_presenters/post.rb +++ b/app/presenters/post_set_presenters/post.rb @@ -1,6 +1,7 @@ module PostSetPresenters - class Post + class Post < Base attr_accessor :post_set, :tag_set_presenter + delegate :posts, :to => :post_set def initialize(post_set) @post_set = post_set @@ -18,26 +19,8 @@ module PostSetPresenters RelatedTagCalculator.calculate_from_sample_to_array(post_set.tag_string).map(&:first) end - def posts - post_set.posts - end - def tag_list_html(template) tag_set_presenter.tag_list_html(template) end - - def post_previews_html(template) - html = "" - - if posts.empty? - return template.render(:partial => "post_sets/blank") - end - - posts.each do |post| - html << PostPresenter.preview(post) - end - - html.html_safe - end end end diff --git a/app/presenters/user_presenter.rb b/app/presenters/user_presenter.rb new file mode 100644 index 000000000..9b3fb0e64 --- /dev/null +++ b/app/presenters/user_presenter.rb @@ -0,0 +1,107 @@ +class UserPresenter + attr_reader :user + + def initialize(user) + @user = user + end + + def level + user.level_string + end + + def ban_reason + if user.is_banned? + "#{user.ban.reason}; expires #{user.ban.expires_at}" + else + nil + end + end + + def tag_subscriptions(template) + user.subscriptions.map do |subscription| + template.link_to(subscription.name, template.tag_subscription_path(subscription)) + end.join("; ") + end + + def upload_limit + deleted_count = Post.for_user(user.id).deleted.count + pending_count = Post.for_user(user.id).pending.count + approved_count = Post.where("is_flagged = false and is_pending = false and user_id = ?", user.id).count + + if user.base_upload_limit + limit = user.base_upload_limit - pending_count + string = "base:#{user.base_upload_limit} - pending:#{pending_count}" + else + limit = 10 + (approved_count / 10) - (deleted_count / 4) - pending_count + string = "base:10 + approved:(#{approved_count} / 10) - deleted:(#{deleted_count}) / 4 - pending:#{pending_count}" + end + + if limit > 20 + limit = 20 + string += " = capped:20" + elsif limit < 0 + limit = 0 + string += " = capped:0" + else + string += " = #{limit}" + end + + return string + end + + def uploads(template) + template.link_to(Post.for_user(user.id).count, template.posts_path(:tags => "uploader:#{user.name}")) + end + + def deleted_uploads(template) + template.link_to(Post.for_user(user.id).deleted.count, template.posts_path(:tags => "status:deleted uploader:#{user.name}")) + end + + def favorites(template) + template.link_to(Favorite.for_user(user.id).count, template.favorites_path(:user_id => user.id)) + end + + def comments(template) + template.link_to(Comment.for_user(user.id).count, template.comments_path(:search => {:creator_id_eq => user.id})) + end + + def post_versions(template) + template.link_to(PostVersion.for_user(user.id).count, template.post_versions_path(:search => {:updater_id_eq => user.id})) + end + + def note_versions(template) + template.link_to(NoteVersion.for_user(user.id).count, template.note_versions_path(:search => {:updater_id_eq => user.id})) + end + + def wiki_page_versions(template) + template.link_to(WikiPageVersion.for_user(user.id).count, template.wiki_page_versions_path(:search => {:updater_id_eq => user.id})) + end + + def forum_posts(template) + template.link_to(ForumPost.for_user(user.id).count, template.forum_posts_path(:search => {:creator_id_eq => user.id})) + end + + def pool_versions(template) + template.link_to(PoolVersion.for_user(user.id).count, template.pool_versions_path(:search => {:updater_id_eq => user.id})) + end + + def inviter(template) + if user.inviter_id + template.link_to(user.inviter.name, template.user_path(user.inviter_id)) + else + nil + end + end + + def approvals(template) + template.link_to(Post.where("approver_id = ?", user.id).count, template.posts_path(:tags => "approver:#{user.name}")) + end + + def feedbacks(template) + positive = UserFeedback.for_user(user.id).positive.count + neutral = UserFeedback.for_user(user.id).neutral.count + negative = UserFeedback.for_user(user.id).negative.count + + template.link_to("positive:#{positive} neutral:#{neutral} negative:#{negative}", user_feedbacks_path(:search => {:user_id_rq => user.id})) + end +end diff --git a/app/views/explore/posts/_date_explore.html.erb b/app/views/explore/posts/_date_explore.html.erb new file mode 100644 index 000000000..b391930dc --- /dev/null +++ b/app/views/explore/posts/_date_explore.html.erb @@ -0,0 +1,19 @@ + diff --git a/app/views/explore/posts/popular.html.erb b/app/views/explore/posts/popular.html.erb new file mode 100644 index 000000000..28440a27f --- /dev/null +++ b/app/views/explore/posts/popular.html.erb @@ -0,0 +1,14 @@ +