diff --git a/Gemfile b/Gemfile index 86300e1e9..7786f5468 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ group :test do gem "faker" end -gem "rails", "3.0.0.beta3" +gem "rails", "3.0.0.rc" gem "pg" gem "memcache-client", :require => "memcache" gem "imagesize", :require => "image_size" diff --git a/Rakefile b/Rakefile index 9cb204643..f18d325ad 100644 --- a/Rakefile +++ b/Rakefile @@ -2,9 +2,6 @@ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require File.expand_path('../config/application', __FILE__) - require 'rake' -require 'rake/testtask' -require 'rake/rdoctask' -Rails::Application.load_tasks +Danbooru::Application.load_tasks diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index dcd6faa0d..77e4d2449 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,7 @@ class ApplicationController < ActionController::Base protect_from_forgery before_filter :set_current_user + after_filter :reset_current_user before_filter :initialize_cookies layout "default" @@ -27,24 +28,29 @@ protected def set_current_user if session[:user_id] - @current_user = User.find_by_id(session[:user_id]) + CurrentUser.user = User.find_by_id(session[:user_id]) + CurrentUser.ip_addr = request.remote_ip end - if @current_user - if @current_user.is_banned? && @current_user.ban && @current_user.ban.expires_at < Time.now - @current_user.update_attribute(:is_banned, false) - Ban.destroy_all("user_id = #{@current_user.id}") + if CurrentUser.user + if CurrentUser.user.is_banned? && CurrentUser.user.ban && CurrentUser.user.ban.expires_at < Time.now + CurrentUser.user.unban! end else - @current_user = AnonymousUser.new + CurrentUser.user = AnonymousUser.new end - Time.zone = @current_user.time_zone + Time.zone = CurrentUser.user.time_zone + end + + def reset_current_user + CurrentUser.user = nil + CurrentUser.ip_addr = nil end %w(member banned privileged contributor janitor moderator admin).each do |level| define_method("#{level}_only") do - if @current_user.__send__("is_#{level}?") + if CurrentUser.user.__send__("is_#{level}?") true else access_denied() @@ -53,10 +59,10 @@ protected end def initialize_cookies - if @current_user.is_anonymous? + if CurrentUser.user.is_anonymous? cookies["blacklisted_tags"] = "" else - cookies["blacklisted_tags"] = @current_user.blacklisted_tags + cookies["blacklisted_tags"] = CurrentUser.user.blacklisted_tags end end end diff --git a/app/controllers/artists_controller.rb b/app/controllers/artists_controller.rb index 2b83ec653..d13fe52c9 100644 --- a/app/controllers/artists_controller.rb +++ b/app/controllers/artists_controller.rb @@ -1,11 +1,16 @@ class ArtistsController < ApplicationController def new + @artist = Artist.new_with_defaults(params) end def edit + @artist = Artist.find(params[:id]) end def index + order = params[:order] == "date" ? "updated_at DESC" : "name" + limit = params[:limit] || 50 + @artists = Artist.paginate(Artist.build_relation()) end def show diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 4171b4be3..672437795 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -2,6 +2,7 @@ class CommentsController < ApplicationController respond_to :html, :xml, :json def index + @posts = Post.paginate :order => "last_commented_at DESC", :per_page => 8 end def update diff --git a/app/controllers/favorites_controller.rb b/app/controllers/favorites_controller.rb index f36237cf8..5b5cff9c5 100644 --- a/app/controllers/favorites_controller.rb +++ b/app/controllers/favorites_controller.rb @@ -1,7 +1,15 @@ class FavoritesController < ApplicationController def create + @favorite = Favorite.create( + :user_id => @current_user.id, + :post_id => params[:favorite][:post_id] + ) end def destroy + Favorite.destroy( + :user_id => @current_user.id, + :post_id => params[:favorite][:post_id] + ) end end diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb index db1e2f370..83bc4d372 100644 --- a/app/helpers/posts_helper.rb +++ b/app/helpers/posts_helper.rb @@ -1,27 +1,16 @@ module PostsHelper - def image_dimensions(post, current_user) - if post.is_image? - "(#{post.image_width_for(current_user)}x#{post.image_height_for(current_user)})" + def resize_image_links(post, user) + links = [] + + links << %{Original} if post.has_medium? || post.has_large? + links << %{Medium} if post.has_medium? + links << %{Large} if post.has_large? + + if links.any? + html = %{} + html.html_safe else "" end end - - def image_dimension_menu(post, current_user) - html = "" - file_size = number_to_human_size(post.file_size) - original_dimensions = post.is_image? ? "(#{post.image_width}x#{post.image_height})" : nil - large_dimensions = post.has_large? ? "(#{post.large_image_width}x#{post.large_image_height})" : nil - medium_dimensions = post.has_medium? ? "(#{post.medium_image_width}x#{post.medium_image_height})" : nil - current_dimensions = "(#{post.image_width_for(current_user)}x#{post.image_height_for(current_user)})" - html << %{} - html << %{
  • #{file_size} #{current_dimensions}
  • } - html << %{} - html << %{
    } - html.html_safe - end end diff --git a/app/logical/favorite.rb b/app/logical/favorite.rb index 1fe2dab49..2ce80c134 100644 --- a/app/logical/favorite.rb +++ b/app/logical/favorite.rb @@ -1,23 +1,60 @@ class Favorite - def self.table_name_for(user) - "favorites_#{user.id % 10}" + attr_accessor :attributes, :errors + + def self.table_name_for(user_id) + "favorites_#{user_id.to_i % 10}" end - def self.create(user, post) - ActiveRecord::Base.connection.execute("INSERT INTO #{table_name_for(user)} (user_id, post_id) VALUES (#{user.id}, #{post.id})") + def self.create(attributes) + user_id = attributes[:user_id] + post_id = attributes[:post_id] + execute_sql("INSERT INTO #{table_name_for(user_id)} (user_id, post_id) VALUES (?, ?)", user_id, post_id) + rescue ActiveRecord::RecordNotUnique + # ignore end - def self.destroy(user, post) - ActiveRecord::Base.connection.execute("DELETE FROM #{table_name_for(user)} WHERE user_id = #{user.id} AND post_id = #{post.id}") + def self.destroy(conditions) + if conditions[:user_id] && conditions[:post_id] + destroy_for_post_and_user(conditions[:post_id], conditions[:user_id]) + elsif conditions[:user_id] + destroy_for_user(conditions[:user_id]) + elsif conditions[:post_id] + destroy_for_post(conditions[:post_id]) + end + end + + def self.exists?(conditions) + if conditions[:user_id] && conditions[:post_id] + select_value_sql("SELECT 1 FROM #{table_name_for(conditions[:user_id])} WHERE user_id = ? AND post_id = ?", conditions[:user_id], conditions[:post_id]) + elsif conditions[:user_id] + select_value_sql("SELECT 1 FROM #{table_name_for(conditions[:user_id])} WHERE user_id = ?", conditions[:user_id]) + elsif conditions[:post_id] + select_value_sql("SELECT 1 FROM #{table_name_for(conditions[:user_id])} WHERE post_id = ?", conditions[:post_id]) + else + false + end + end + +private + def self.destroy_for_post_and_user(post_id, user_id) + execute_sql("DELETE FROM #{table_name_for(user_id)} WHERE post_id = #{post_id} AND user_id = #{user_id}") end - def self.destroy_all_for_post(post) + def self.destroy_for_post(post) 0.upto(9) do |i| - ActiveRecord::Base.connection.execute("DELETE FROM favorites_#{i} WHERE post_id = #{post.id}") + execute_sql("DELETE FROM favorites_#{i} WHERE post_id = #{post.id}") end end - def self.destroy_all_for_user(user) - ActiveRecord::Base.connection.execute("DELETE FROM #{table_name_for(user)} WHERE user_id = #{user.id}") + def self.destroy_for_user(user) + execute_sql("DELETE FROM #{table_name_for(user)} WHERE user_id = #{user.id}") + end + + def self.select_value_sql(sql, *params) + ActiveRecord::Base.select_value_sql(sql, *params) + end + + def self.execute_sql(sql, *params) + ActiveRecord::Base.execute_sql(sql, *params) end end diff --git a/app/models/artist.rb b/app/models/artist.rb index 5d5332ed2..bac0afa27 100644 --- a/app/models/artist.rb +++ b/app/models/artist.rb @@ -3,7 +3,7 @@ class Artist < ActiveRecord::Base before_create :initialize_creator before_save :normalize_name after_save :create_version - after_save :commit_url_string + after_save :save_url_string validates_uniqueness_of :name validates_presence_of :updater_id, :updater_ip_addr belongs_to :updater, :class_name => "User" @@ -36,7 +36,7 @@ class Artist < ActiveRecord::Base m.extend(ClassMethods) end - def commit_url_string + def save_url_string if @url_string artist_urls.clear @@ -82,7 +82,7 @@ class Artist < ActiveRecord::Base module UpdaterMethods def updater_name - User.find_name(updater_id).tr("_", " ") + User.id_to_name(updater_id).tr("_", " ") end end @@ -150,12 +150,35 @@ class Artist < ActiveRecord::Base end end + module FactoryMethods + def new_with_defaults(params) + returning(Artist.new) do |artist| + if params[:name] + artist.name = params[:name] + post = Post.find_by_tags("source:http* #{artist.name}").first + unless post.nil? || post.source.blank? + artist.url_string = post.source + end + end + + if params[:other_names] + artist.other_names = params[:other_names] + end + + if params[:urls] + artist.url_string = params[:urls] + end + end + end + end + include UrlMethods include NameMethods include GroupMethods include UpdaterMethods extend SearchMethods include VersionMethods + extend FactoryMethods def initialize_creator if creator.nil? diff --git a/app/models/artist_version.rb b/app/models/artist_version.rb index 756bb2cde..d4c71129a 100644 --- a/app/models/artist_version.rb +++ b/app/models/artist_version.rb @@ -3,6 +3,6 @@ class ArtistVersion < ActiveRecord::Base belongs_to :artist def updater_name - User.find_name(updater_id).tr("_", " ") + User.id_to_name(updater_id).tr("_", " ") end end diff --git a/app/models/comment.rb b/app/models/comment.rb index e31f5f9dd..5c81126f9 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -13,7 +13,7 @@ class Comment < ActiveRecord::Base scope :hidden, lambda {|user| where("score < ?", user.comment_threshold)} def creator_name - User.find_name(creator_id) + User.id_to_name(creator_id) end def validate_creator_is_not_limited diff --git a/app/models/dmail.rb b/app/models/dmail.rb index 376c9a3fd..1ce321df3 100644 --- a/app/models/dmail.rb +++ b/app/models/dmail.rb @@ -18,11 +18,11 @@ class Dmail < ActiveRecord::Base module AddressMethods def to_name - User.find_pretty_name(to_id) + User.id_to_pretty_name(to_id) end def from_name - User.find_pretty_name(from_id) + User.id_to_pretty_name(from_id) end def to_name=(name) diff --git a/app/models/job.rb b/app/models/job.rb index c4e9e5843..57f322371 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -120,7 +120,7 @@ class Job < ActiveRecord::Base when "mass_tag_edit" start = data["start_tags"] result = data["result_tags"] - user = User.find_name(data["updater_id"]) + user = User.id_to_name(data["updater_id"]) "start:#{start} result:#{result} user:#{user}" when "approve_tag_alias" diff --git a/app/models/note.rb b/app/models/note.rb index 113fd6f30..02014d2f3 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -37,7 +37,7 @@ class Note < ActiveRecord::Base end def creator_name - User.find_name(creator_id) + User.id_to_name(creator_id) end def update_post diff --git a/app/models/note_version.rb b/app/models/note_version.rb index 14d88626a..d9ca9a646 100644 --- a/app/models/note_version.rb +++ b/app/models/note_version.rb @@ -1,5 +1,5 @@ class NoteVersion < ActiveRecord::Base def updater_name - User.find_name(updater_id) + User.id_to_name(updater_id) end end diff --git a/app/models/pool.rb b/app/models/pool.rb index 62c1bec60..156b1001e 100644 --- a/app/models/pool.rb +++ b/app/models/pool.rb @@ -6,9 +6,14 @@ class Pool < ActiveRecord::Base belongs_to :creator, :class_name => "User" belongs_to :updater, :class_name => "User" has_many :versions, :class_name => "PoolVersion", :dependent => :destroy + before_save :normalize_name after_save :create_version attr_accessible :name, :description, :post_ids, :is_public, :is_active + def self.name_to_id(name) + select_value_sql("SELECT id FROM pools WHERE name = ?", name.downcase) + end + def self.create_anonymous(creator, creator_ip_addr) Pool.new do |pool| pool.name = "TEMP:#{Time.now.to_f}.#{rand(1_000_000)}" @@ -21,6 +26,10 @@ class Pool < ActiveRecord::Base end end + def normalize_name + self.name = name.downcase + end + def revert_to!(version) self.post_ids = version.post_ids save diff --git a/app/models/post.rb b/app/models/post.rb index 5cc253bd6..670cebda2 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,9 +1,8 @@ class Post < ActiveRecord::Base - attr_accessor :updater_id, :updater_ip_addr, :old_tag_string, :should_create_pool + attr_accessor :old_tag_string, :old_parent_id after_destroy :delete_files - after_destroy :delete_favorites - after_destroy :update_tag_post_counts after_save :create_version + after_save :update_parent_on_save before_save :merge_old_tags before_save :normalize_tags before_save :create_tags @@ -11,6 +10,7 @@ class Post < ActiveRecord::Base before_save :set_tag_counts belongs_to :updater, :class_name => "User" belongs_to :approver, :class_name => "User" + belongs_to :parent, :class_name => "Post" has_one :unapproval, :dependent => :destroy has_one :upload, :dependent => :destroy has_one :moderation_detail, :class_name => "PostModerationDetail", :dependent => :destroy @@ -18,9 +18,11 @@ class Post < ActiveRecord::Base has_many :votes, :class_name => "PostVote", :dependent => :destroy has_many :notes, :dependent => :destroy has_many :comments - validates_presence_of :updater_id, :updater_ip_addr + has_many :children, :class_name => "Post", :foreign_key => "parent_id", :order => "posts.id" validates_uniqueness_of :md5 - attr_accessible :source, :rating, :tag_string, :old_tag_string, :updater_id, :updater_ip_addr, :last_noted_at + validates_presence_of :parent, :if => lambda {|rec| !rec.parent_id.nil?} + validate :validate_parent_does_not_have_a_parent + attr_accessible :source, :rating, :tag_string, :old_tag_string, :last_noted_at module FileMethods def delete_files @@ -179,13 +181,13 @@ class Post < ActiveRecord::Base end end - module ModerationMethods - def unapprove!(reason, current_user, current_ip_addr) + module ApprovalMethods + def unapprove!(reason) raise Unapproval::Error.new("You can't unapprove a post more than once") if is_flagged? unapproval = create_unapproval( - :unapprover_id => current_user.id, - :unapprover_ip_addr => current_ip_addr, + :unapprover_id => CurrentUser.user.id, + :unapprover_ip_addr => CurrentUser.ip_addr, :reason => reason ) @@ -193,15 +195,13 @@ class Post < ActiveRecord::Base raise Unapproval::Error.new(unapproval.errors.full_messages.join("; ")) end - update_attribute(:is_flagged, true) + toggle!(:is_flagged) end - - def delete! - update_attribute(:is_deleted, true) - end - + def approve! - update_attributes(:is_deleted => false, :is_pending => false) + update_attributes( + :is_pending => false + ) end end @@ -226,19 +226,17 @@ class Post < ActiveRecord::Base :source => source, :rating => rating, :tag_string => tag_string, - :updater_id => updater_id, - :updater_ip_addr => updater_ip_addr + :updater_id => CurrentUser.user.id, + :updater_ip_addr => CurrentUser.ip_addr ) raise PostVersion::Error.new(version.errors.full_messages.join("; ")) if version.errors.any? end - def revert_to!(version, reverter_id, reverter_ip_addr) + def revert_to!(version) self.source = version.source self.rating = version.rating self.tag_string = version.tag_string - self.updater_id = reverter_id - self.updater_ip_addr = reverter_ip_addr save! end end @@ -256,6 +254,14 @@ class Post < ActiveRecord::Base set_tag_string(tag_array.map {|x| Tag.find_or_create_by_name(x).name}.join(" ")) end + def increment_tag_post_counts + execute_sql("UPDATE tags SET post_count = post_count + 1 WHERE name IN (?)", tag_array) if tag_array.any? + end + + def decrement_tag_post_counts + execute_sql("UPDATE tags SET post_count = post_count - 1 WHERE name IN (?)", tag_array) if tag_array.any? + end + def update_tag_post_counts decrement_tags = tag_array_was - tag_array increment_tags = tag_array - tag_array_was @@ -333,19 +339,44 @@ class Post < ActiveRecord::Base module FavoriteMethods def delete_favorites - Favorite.destroy_all_for_post(self) + Favorite.destroy_for_post(self) end def add_favorite(user) - self.fav_string += " fav:#{user.name}" + if user.is_a?(ActiveRecord::Base) + user_id = user.id + else + user_id = user + end + + return false if fav_string =~ /fav:#{user_id}/ + self.fav_string += " fav:#{user_id}" self.fav_string.strip! - Favorite.create(user, self) + + # in order to avoid rerunning the callbacks, just update through raw sql + execute_sql("UPDATE posts SET fav_string = ? WHERE id = ?", fav_string, id) + + Favorite.create(:user_id => user_id, :post_id => id) end def remove_favorite(user) - self.fav_string.gsub!(/(?:\A| )fav:#{user.name}(?:\Z| )/, " ") + if user.is_a?(ActiveRecord::Base) + user_id = user.id + else + user_id = user + end + + self.fav_string.gsub!(/(?:\A| )fav:#{user_id}(?:\Z| )/, " ") self.fav_string.strip! - Favorite.destroy(user, self) + + # in order to avoid rerunning the callbacks, just update through raw sql + execute_sql("UPDATE posts SET fav_string = ? WHERE id = ?", fav_string, id) + + Favorite.destroy(:user_id => user_id, :post_id => id) + end + + def favorited_user_ids + fav_string.scan(/\d+/) end end @@ -435,7 +466,11 @@ class Post < ActiveRecord::Base q = Tag.parse_query(q) end - relation = where() + if q[:status] == "deleted" + relation = RemovedPost.where() + else + relation = where() + end relation = add_range_relation(q[:post_id], "posts.id", relation) relation = add_range_relation(q[:mpixels], "posts.width * posts.height / 1000000.0", relation) @@ -458,14 +493,10 @@ class Post < ActiveRecord::Base relation = relation.where(["posts.md5 IN (?)", q[:md5]]) end - if q[:status] == "deleted" - relation = relation.where("posts.is_deleted = TRUE") - elsif q[:status] == "pending" + if q[:status] == "pending" relation = relation.where("posts.is_pending = TRUE") elsif q[:status] == "flagged" relation = relation.where("posts.is_flagged = TRUE") - else - relation = relation.where("posts.is_deleted = FALSE") end if q[:source].is_a?(String) @@ -477,7 +508,7 @@ class Post < ActiveRecord::Base end relation = add_tag_string_search_relation(q[:tags], relation) - + if q[:rating] == "q" relation = relation.where("posts.rating = 'q'") elsif q[:rating] == "s" @@ -553,31 +584,31 @@ class Post < ActiveRecord::Base end def uploader_id - uploader.id - end - - def uploader_name uploader_string[9..-1] end + def uploader_name + User.id_to_name(uploader_id) + end + def uploader - User.find_by_name(uploader_name) + User.find(uploader_id) end def uploader=(user) - self.uploader_string = "uploader:#{user.name}" + self.uploader_string = "uploader:#{user.id}" end end module PoolMethods def add_pool(pool) - self.pool_string += " pool:#{pool.name}" + self.pool_string += " pool:#{pool.id}" self.pool_string.strip! pool.add_post!(self) end def remove_pool(pool) - self.pool_string.gsub!(/(?:\A| )pool:#{pool.name}(?:\Z| )/, " ") + self.pool_string.gsub!(/(?:\A| )pool:#{pool.id}(?:\Z| )/, " ") self.pool_string.strip! pool.remove_post!(self) end @@ -631,9 +662,106 @@ class Post < ActiveRecord::Base end end + module ParentMethods + # A parent has many children. A child belongs to a parent. + # A parent cannot have a parent. + # + # After deleting a child: + # - Move favorites to parent. + # - Does the parent have any active children? + # - Yes: Done. + # - No: Update parent's has_children flag to false. + # + # After deleting a parent: + # - Move favorites to the first child. + # - Reparent all active children to the first active child. + + module ClassMethods + def update_has_children_flag_for(post_id) + has_children = Post.exists?(["parent_id = ?", post_id]) + execute_sql("UPDATE posts SET has_children = ? WHERE id = ?", has_children, post_id) + end + + def recalculate_has_children_for_all_posts + transaction do + execute_sql("UPDATE posts SET has_children = false WHERE has_children = true") + execute_sql("UPDATE posts SET has_children = true WHERE id IN (SELECT p.parent_id FROM posts p WHERE p.parent_id IS NOT NULL)") + end + end + end + + def self.included(m) + m.extend(ClassMethods) + end + + def validate_parent_does_not_have_a_parent + return if parent.nil? + if !parent.parent.nil? + errors.add(:parent, "can not have a parent") + end + end + + def update_parent_on_destroy + Post.update_has_children_flag_for(parent_id) + Post.update_has_children_flag_for(parent_id_was) if parent_id_was && parent_id != parent_id_was + end + + def update_children_on_destroy + if children.size == 0 + # do nothing + elsif children.size == 1 + children.first.update_attribute(:parent_id, nil) + else + cached_children = children + cached_children[1..-1].each do |child| + child.update_attribute(:parent_id, cached_children[0].id) + end + cached_children[0].update_attribute(:parent_id, nil) + end + end + + def update_parent_on_save + if parent_id == parent_id_was + # do nothing + elsif !parent_id_was.nil? + Post.update_has_children_flag_for(parent_id) + Post.update_has_children_flag_for(parent_id_was) + else + Post.update_has_children_flag_for(parent_id) + end + end + + def give_favorites_to_parent + return if parent.nil? + + favorited_user_ids.each do |user_id| + parent.add_favorite(user_id) + remove_favorite(user_id) + end + end + + def delete_favorites + Favorite.destroy_for_post(self) + end + end + + module RemovalMethods + def remove! + Post.transaction do + execute_sql("INSERT INTO removed_posts (#{Post.column_names.join(', ')}) SELECT #{Post.column_names.join(', ')} FROM posts WHERE posts.id = #{id}") + give_favorites_to_parent + update_children_on_destroy + delete_favorites + decrement_tag_post_counts + execute_sql("DELETE FROM posts WHERE id = #{id}") + update_parent_on_destroy + end + end + end + include FileMethods include ImageMethods - include ModerationMethods + include ApprovalMethods include PresenterMethods include VersionMethods include TagMethods @@ -644,6 +772,8 @@ class Post < ActiveRecord::Base include VoteMethods extend CountMethods include CacheMethods + include ParentMethods + include RemovalMethods def reload(options = nil) super diff --git a/app/models/tag.rb b/app/models/tag.rb index 62c32c0c1..f2d43f200 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -217,22 +217,22 @@ class Tag < ActiveRecord::Base if token =~ /\A(-uploader|uploader|-pool|pool|-fav|fav|sub|md5|-rating|rating|width|height|mpixels|score|filesize|source|id|date|order|status|tagcount|gentags|arttags|chartags|copytags):(.+)\Z/ case $1 when "-uploader" - q[:tags][:exclude] << token[1..-1] + q[:tags][:exclude] << "uploader:#{User.name_to_id(token[1..-1])}" when "uploader" - q[:tags][:related] << token + q[:tags][:related] << "uploader:#{User.name_to_id(token)}" when "-pool" - q[:tags][:exclude] << token[1..-1] + q[:tags][:exclude] << "pool:#{Pool.name_to_id(token[1..-1])}" when "pool" - q[:tags][:related] << token + q[:tags][:related] << "pool:#{Pool.name_to_id(token)}" when "-fav" - q[:tags][:exclude] << token[1..-1] + q[:tags][:exclude] << "fav:#{User.name_to_id(token[1..-1])}" when "fav" - q[:tags][:related] << token + q[:tags][:related] << "fav:#{User.name_to_id(token)}" when "sub" q[:subscriptions] << $2 diff --git a/app/models/user.rb b/app/models/user.rb index 8e0a40ba0..d994d01f3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -20,6 +20,7 @@ class User < ActiveRecord::Base before_create :promote_to_admin_if_first_user before_create :normalize_level has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy + has_one :ban belongs_to :inviter, :class_name => "User" scope :named, lambda {|name| where(["lower(name) = ?", name])} @@ -30,12 +31,23 @@ class User < ActiveRecord::Base return false end end + + def unban! + update_attribute(:is_banned, false) + ban.destroy + end end module NameMethods module ClassMethods - def find_name(user_id) - Cache.get("un:#{user_id}") do + def name_to_id(name) + Cache.get("uni:#{Cache.sanitize(name)}") do + select_value_sql("SELECT id FROM users WHERE name = ?", name.downcase) + end + end + + def id_to_name(user_id) + Cache.get("uin:#{user_id}") do select_value_sql("SELECT name FROM users WHERE id = ?", user_id) || Danbooru.config.default_guest_name end end @@ -44,8 +56,8 @@ class User < ActiveRecord::Base where(["lower(name) = ?", name.downcase]).first end - def find_pretty_name(user_id) - find_name.tr("_", " ") + def id_to_pretty_name(user_id) + id_to_name.tr("_", " ") end end @@ -58,7 +70,7 @@ class User < ActiveRecord::Base end def update_cache - Cache.put("un:#{id}", name) + Cache.put("uin:#{id}", name) end end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 8e3cde121..b14b34592 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -45,7 +45,7 @@ class WikiPage < ActiveRecord::Base end def creator_name - User.find_name(user_id).tr("_", " ") + User.id_to_name(user_id).tr("_", " ") end def pretty_title diff --git a/app/models/wiki_page_version.rb b/app/models/wiki_page_version.rb index 43bea5863..199ea5464 100644 --- a/app/models/wiki_page_version.rb +++ b/app/models/wiki_page_version.rb @@ -3,7 +3,7 @@ class WikiPageVersion < ActiveRecord::Base belongs_to :updater def updater_name - User.find_name(updater_id) + User.id_to_name(updater_id) end def pretty_title diff --git a/app/views/layouts/default.html.erb b/app/views/layouts/default.html.erb index 948c84da0..252069d4e 100644 --- a/app/views/layouts/default.html.erb +++ b/app/views/layouts/default.html.erb @@ -10,7 +10,8 @@ <% end %> <%= auto_discovery_link_tag :atom, posts_path(:format => "atom", :tags => params[:tags]) %> <%= stylesheet_link_tag "default" %> - <%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" %> + <%#= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" %> + <%= javascript_include_tag "jquery.min.js" %> <%= javascript_include_tag "rails" %> <%= javascript_include_tag "application" %> <%= Danbooru.config.custom_html_header_content %> diff --git a/app/views/posts/partials/show/_image.html.erb b/app/views/posts/partials/show/_image.html.erb index 0aaaa4a94..d98c3f2b6 100644 --- a/app/views/posts/partials/show/_image.html.erb +++ b/app/views/posts/partials/show/_image.html.erb @@ -1,2 +1,2 @@ <%= render :partial => "posts/partials/show/notes", :locals => {:post => post, :notes => post.notes.active} %> -<%= image_tag(post.file_url_for(@current_user), :alt => post.tag_string, :width => post.image_width_for(@current_user), :height => post.image_height_for(@current_user), "data-original-width" => post.image_width, "data-original-height" => post.image_height) %> +<%= image_tag(post.file_url_for(@current_user), :alt => post.tag_string, :width => post.image_width_for(@current_user), :height => post.image_height_for(@current_user), :id => "image") %> diff --git a/app/views/posts/partials/show/_information.html.erb b/app/views/posts/partials/show/_information.html.erb index 09f0d6c76..d7e77ef31 100644 --- a/app/views/posts/partials/show/_information.html.erb +++ b/app/views/posts/partials/show/_information.html.erb @@ -6,7 +6,10 @@
  • Approver: <%= link_to(post.approver.name, user_path(post.approver_id)) %>
  • <% end %>
  • - Size: <%= image_dimension_menu(post, @current_user) %> + Size: <%= number_to_human_size(post.file_size) %> + <% if post.is_image? %> + (<%= post.image_width %>x<%= post.image_height %>) + <% end %>
  • <%= link_to "Tag History", post_versions_path(:post_id => post) %>
  • <%= link_to "Note History", note_versions_path(:post_id => post) %>
  • diff --git a/app/views/posts/partials/show/_options.html.erb b/app/views/posts/partials/show/_options.html.erb index f4dcdbeb7..8c15457b5 100644 --- a/app/views/posts/partials/show/_options.html.erb +++ b/app/views/posts/partials/show/_options.html.erb @@ -1,7 +1,5 @@