fixed upload->post converion process

This commit is contained in:
albert
2010-03-17 19:20:44 -04:00
parent ca8be10ab9
commit dcf8d0df4c
20 changed files with 346 additions and 100 deletions

View File

@@ -9,6 +9,11 @@ class UploadsController < ApplicationController
end
end
def index
@uploads = Upload.where("uploader_id = ?", @current_user.id).includes(:uploader).order("uploads.id desc").limit(10)
respond_with(@uploads)
end
def show
@upload = Upload.find(params[:id])
end

View File

@@ -12,7 +12,9 @@ class Favorite
end
def self.destroy_all_for_post(post)
ActiveRecord::Base.connection.execute("DELETE FROM #{table_name_for(user)} WHERE post_id = #{post.id}")
0.upto(9) do |i|
ActiveRecord::Base.connection.execute("DELETE FROM favorites_#{i} WHERE post_id = #{post.id}")
end
end
def self.destroy_all_for_user(user)

View File

@@ -1,7 +1,7 @@
class PostSet
class Error < Exception ; end
attr_accessor :tags, :page, :current_user, :before_id, :errors
attr_accessor :tags, :page, :current_user, :before_id, :errors, :count
attr_accessor :wiki_page, :artist, :posts, :suggestions
def initialize(tags, page, current_user, before_id = nil)
@@ -11,16 +11,24 @@ class PostSet
@before_id = before_id
@errors = []
load_associations
load_paginator
load_posts
validate
end
def use_sequential_paginator?
!use_numbered_paginator?
end
def use_numbered_paginator?
before_id.nil?
end
def has_errors?
errors.any?
end
def offset
x = (page - 1) * 20
x = (page - 1) * limit
if x < 0
x = 0
end
@@ -28,7 +36,7 @@ class PostSet
end
def limit
20
Danbooru.config.posts_per_page
end
def is_single_tag?
@@ -42,28 +50,13 @@ class PostSet
end
end
def load_paginator
if before_id
load_sequential_paginator
else
load_paginated_paginator
end
end
def load_paginated_paginator
def load_posts
@count = Post.fast_count(tags)
@posts = Post.find_by_tags(tags, :before_id => before_id).all(:order => "posts.id desc", :limit => limit, :offset => offset)
end
def load_sequential_paginator
count = Post.fast_count(tags)
@posts = WillPaginate::Collection.create(page, limit, count) do |pager|
pager.replace(Post.find_by_sql(tags).all(:order => "posts.id desc", :limit => pager.per_page, :offset => pager.offset))
end
load_suggestions(count)
end
def load_suggestions(count)
@suggestions = Tag.find_suggestions(tags) if count < 20 && is_single_tag?
@suggestions = Tag.find_suggestions(tags) if count < limit && is_single_tag?
end
def tag_array

View File

@@ -2,6 +2,7 @@ class Post < ActiveRecord::Base
attr_accessor :updater_id, :updater_ip_addr, :old_tag_string
after_destroy :delete_files
after_destroy :delete_favorites
after_destroy :update_tag_post_counts
after_save :create_version
before_save :merge_old_tags
before_save :normalize_tags
@@ -9,6 +10,7 @@ class Post < ActiveRecord::Base
before_save :update_tag_post_counts
before_save :set_tag_counts
belongs_to :updater, :class_name => "User"
belongs_to :approver, :class_name => "User"
has_one :unapproval, :dependent => :destroy
has_one :upload, :dependent => :destroy
has_one :moderation_detail, :class_name => "PostModerationDetail", :dependent => :destroy
@@ -16,6 +18,7 @@ class Post < ActiveRecord::Base
has_many :votes, :class_name => "PostVote", :dependent => :destroy
has_many :notes, :dependent => :destroy
validates_presence_of :updater_id, :updater_ip_addr
validates_uniqueness_of :md5
attr_accessible :source, :rating, :tag_string, :old_tag_string, :updater_id, :updater_ip_addr, :last_noted_at
module FileMethods
@@ -74,6 +77,10 @@ class Post < ActiveRecord::Base
file_url
end
end
def is_image?
file_ext =~ /jpg|gif|png/
end
end
module ImageMethods
@@ -168,6 +175,12 @@ class Post < ActiveRecord::Base
increment_tags = tag_array - tag_array_was
execute_sql("UPDATE tags SET post_count = post_count - 1 WHERE name IN (?)", decrement_tags) if decrement_tags.any?
execute_sql("UPDATE tags SET post_count = post_count + 1 WHERE name IN (?)", increment_tags) if increment_tags.any?
decrement_tags.each do |tag|
expire_cache(tag)
end
increment_tags.each do |tag|
expire_cache(tag)
end
end
def set_tag_counts
@@ -501,15 +514,32 @@ class Post < ActiveRecord::Base
module CountMethods
def fast_count(tags)
Cache.get("pfc:#{Cache.sanitize(tags)}", 24.hours) do
Post.find_by_tags(tags).count
end
count = Cache.get("pfc:#{Cache.sanitize(tags)}")
return count unless count.nil?
count = Post.find_by_tags(tags).count
expiry = (count < 100) ? 0 : (count * 4).minutes
Cache.put("pfc:#{Cache.sanitize(tags)}", count, expiry)
count
end
def fast_delete_count(tags)
Cache.get("pfdc:#{Cache.sanitize(tags)}", 24.hours) do
Post.find_by_tags("#{tags} status:deleted").count
count = Cache.get("pfdc:#{Cache.sanitize(tags)}")
return count unless count.nil?
count = Post.find_by_tags("#{tags} status:deleted").count
expiry = (count < 100) ? 0 : (count * 4).minutes
Cache.put("pfc:#{Cache.sanitize(tags)}", count, expiry)
count
end
end
module CacheMethods
def expire_cache(tag_name)
if Post.fast_count("") < 1000
Cache.delete("pfc:")
Cache.delete("pfdc:")
end
Cache.delete("pfc:#{Cache.sanitize(tag_name)}")
Cache.delete("pfdc:#{Cache.sanitize(tag_name)}")
end
end
@@ -525,9 +555,14 @@ class Post < ActiveRecord::Base
extend SearchMethods
include VoteMethods
extend CountMethods
include CacheMethods
def reload(options = nil)
super
reset_tag_array_cache
end
def presenter
@presenter ||= PostPresenter.new(self)
end
end

View File

@@ -18,6 +18,12 @@ class Upload < ActiveRecord::Base
raise
end
end
# Because uploads are processed serially, there's no race condition here.
def validate_md5_uniqueness
md5_post = Post.find_by_md5(md5)
merge_tags(md5_post) if md5_post
end
def validate_file_exists
unless File.exists?(file_path)
@@ -51,6 +57,7 @@ class Upload < ActiveRecord::Base
self.file_ext = content_type_to_file_ext(content_type)
validate_file_content_type
calculate_hash(file_path)
validate_md5_uniqueness
validate_md5_confirmation
calculate_file_size(file_path)
calculate_dimensions(file_path) if has_dimensions?
@@ -85,6 +92,15 @@ class Upload < ActiveRecord::Base
end
end
end
def merge_tags(post)
post.tag_string += " #{tag_string}"
post.updater_id = uploader_id
post.updater_ip_addr = uploader_ip_addr
post.save
update_attribute(:status, "duplicate: #{post.id}")
raise
end
end
module FileMethods
@@ -274,4 +290,8 @@ class Upload < ActiveRecord::Base
include FilePathMethods
include CgiFileMethods
include StatusMethods
def presenter
@presenter ||= UploadPresenter.new(self)
end
end

View File

@@ -1,2 +1,2 @@
class PaginatorPresenter
class PaginatorPresenter < Presenter
end

View File

@@ -0,0 +1,14 @@
class PostPresenter < Presenter
def initialize(post)
@post = post
end
def tag_list_html
end
def image_html
end
def note_html
end
end

View File

@@ -1,3 +1,5 @@
require 'pp'
class PostSetPresenter < Presenter
attr_accessor :post_set
@@ -17,7 +19,80 @@ class PostSetPresenter < Presenter
""
end
def pagination_html
def pagination_html(template)
if @post_set.use_sequential_paginator?
sequential_pagination_html(template)
else
numbered_pagination_html(template)
end
end
def sequential_pagination_html(template)
html = "<menu>"
prev_url = template.request.env["HTTP_REFERER"]
next_url = template.posts_path(:tags => template.params[:tags], before_id => @post_set.posts[-1].id, :page => nil)
html << %{<li><a href="#{prev_url}">&laquo; Previous</a></li>}
if @post_set.posts.any?
html << %{<li><a href="#{next_url}">Next &raquo;</a></li>}
end
html << "</menu>"
html.html_safe
end
def numbered_pagination_html(template)
total_pages = (@post_set.count.to_f / @post_set.limit.to_f).ceil
current_page = [1, @post_set.page].max
before_current_page = current_page - 1
after_current_page = current_page + 1
html = "<menu>"
current_page_min = [1, current_page - 2].max
current_page_max = [total_pages, current_page + 2].min
if current_page == 1
# do nothing
elsif current_page_min == 1
1.upto(before_current_page) do |i|
html << numbered_pagination_item(template, i)
end
else
1.upto(3) do |i|
html << numbered_pagination_item(template, i)
end
html << "<li>...</li>"
current_page_min.upto(before_current_page) do |i|
html << numbered_pagination_item(template, i)
end
end
html << %{<li class="current-page">#{current_page}</li>}
if current_page == total_pages
# do nothing
elsif current_page_max == total_pages
after_current_page.upto(total_pages) do|i|
html << numbered_pagination_item(template, i)
end
else
after_current_page.upto(after_current_page + 2) do |i|
html << numbered_pagination_item(template, i)
end
html << "<li>...</li>"
html << numbered_pagination_item(template, total_pages)
end
html << "</menu>"
html.html_safe
end
def numbered_pagination_item(template, page)
html = "<li>"
html << template.link_to(page, template.__send__(:posts_path, :tags => template.params[:tags], :page => page))
html << "</li>"
html.html_safe
end
def post_previews_html

View File

@@ -0,0 +1,15 @@
class UploadPresenter < Presenter
def initialize(upload)
@upload = upload
end
def status(template)
case @upload.status
when /duplicate: (\d+)/
template.link_to(@upload.status, template.__send__(:post_path, $1))
else
@upload.status
end
end
end

View File

@@ -13,63 +13,43 @@
<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" %>
<%= javascript_include_tag "rails" %>
<%= Danbooru.config.custom_html_header_content %>
<%= yield :html_header_content %>
<%= yield :html_header %>
</head>
<body>
<nav>
<h1><%= link_to(Danbooru.config.app_name, "/") %><%= yield :page_title %></h1>
<menu>
<% if @current_user.is_anonymous? %>
<%= nav_link_to("Login", new_session_path) %>
<% else %>
<%= nav_link_to("My Account", user_path(@current_user)) %>
<% end %>
<%= nav_link_to("Posts", posts_path) %>
<%= nav_link_to("Comments", comments_path) %>
<%= nav_link_to("Notes", notes_path) %>
<%= nav_link_to("Artists", artists_path(:order => "date")) %>
<%= nav_link_to("Tags", tags_path(:order => "date")) %>
<%= nav_link_to("Pools", pools_path) %>
<%= nav_link_to("Wiki", wiki_page_path(:id => "help:home")) %>
<%= nav_link_to("Forum", forum_topics_path, :class => (@current_user.has_forum_been_updated? ? "forum-updated" : nil)) %>
<%= nav_link_to("&raquo;".html_safe, site_map_path) %>
</menu>
<%= yield :secondary_nav_links %>
</nav>
<header>
<nav>
<menu>
<% if @current_user.is_anonymous? %>
<%= nav_link_to("Login", new_session_path) %>
<% else %>
<%= nav_link_to("My Account", user_path(@current_user)) %>
<% end %>
<%= nav_link_to("Posts", posts_path) %>
<%= nav_link_to("Comments", comments_path) %>
<%= nav_link_to("Notes", notes_path) %>
<%= nav_link_to("Artists", artists_path(:order => "date")) %>
<%= nav_link_to("Tags", tags_path(:order => "date")) %>
<%= nav_link_to("Pools", pools_path) %>
<%= nav_link_to("Wiki", wiki_page_path(:id => "help:home")) %>
<%= nav_link_to("Forum", forum_topics_path, :class => (@current_user.has_forum_been_updated? ? "forum-updated" : nil)) %>
<%= nav_link_to("&raquo;".html_safe, site_map_path) %>
</menu>
<%= yield :secondary_nav_links %>
</nav>
</header>
<% if flash[:notice] %>
<div id="notice"><%= flash[:notice] %></div>
<% else %>
<div id="notice" style="display: none;"></div>
<% end %>
<% if @current_user.has_mail? %>
<div class="has-mail" id="has-mail-notice">
<%= link_to "You have mail", dmails_path %>
</div>
<% end %>
<% if !@current_user.is_privileged? %>
<div id="upgrade-account" style="display: none;">
<%= link_to "Upgrade your account for only $20", wiki_page_path(:id => "help:users") %>
<%= link_to "No thanks", "#", :id => "hide-upgrade-account-link" %>
</div>
<% end %>
<% if @current_user.is_banned? %>
<div id="ban-reason">
You have been banned.
<% if @current_user.ban %>
Reason: <%= @current_user.ban.reason %>.
Expires: <%= @current_user.ban.expires_at.strftime('%Y-%m-%d') %>
<% end %>
</div>
<% end %>
<div id="content">
<%= yield :layout %>
</div>
<%= yield :page_footer_content %>
<footer>
<%= yield :page_footer_content %>
</footer>
</body>
</html>

View File

@@ -1,6 +1,6 @@
<% content_for(:secondary_nav_links) do %>
<menu>
<li>Listing</li>
<li><%= link_to "Listing", posts_path %></li>
<li><%= link_to "Upload", new_upload_path %></li>
<li>Popular</li>
<li>Favorites</li>
@@ -10,4 +10,4 @@
<li>Moderate</li>
<li>Help</li>
</menu>
<% end %>
<% end %>

View File

@@ -71,14 +71,10 @@
</section>
<footer>
<%= @post_set.presenter.pagination_html %>
<%= @post_set.presenter.pagination_html(self) %>
</footer>
<% content_for(:page_title) do %>
/<%= @post_set.tags %>
<% end %>
<% content_for(:page_header) do %>
/ <%= @post_set.tags %>
<% end %>

View File

@@ -0,0 +1,87 @@
<aside>
<section>
<h1>Search</h1>
<% form_tag(posts_path, :method => "get") do %>
<%= text_field_tag("tags", params[:tags], :size => 20) %>
<%= submit_tag "Go" %>
<% end %>
</section>
<section>
<h1>Tags</h1>
<%= @post.presenter.tag_list_html %>
</section>
<section>
<h1>Information</h1>
<ul>
<li>Id: <%= @post.id %></li>
<li>Uploaded <%= time_ago_in_words(@post.created_at) %> ago by <%= link_to_unless(@post.uploader.nil?, @post.uploader_name, user_path(@post.uploader)) %></li>
<% if @post.approver %>
<li>Approver: <%= @post.approver.name %></li>
<% end %>
<% if @post.is_image? %>
<li>
[M]
[L]
[O]
</li>
<% end %>
<li><%= link_to "Tag History", post_versions_path(:post_id => @post) %></li>
<li><%= link_to "Note History", note_versions_path(:post_id => @post) %></li>
</ul>
</section>
<section>
<h1>Options</h1>
<menu>
<% if !@post.is_deleted? && @post.is_image? && @post.image_width && @post.image_width > 700 %>
<li><%= link_to "Resize", "#" %></li>
<% end %>
<li><%= link_to "Favorite", "#" %></li>
<li><%= link_to "Unfavorite", "#" %></li>
<li><%= link_to "Add translation", "#" %></li>
<li><%= link_to "Unapprove", "#" %></li>
<% if @current_user.is_janitor? %>
<li><%= link_to "Approve", "#" %></li>
<li><%= link_to "Undelete", "#" %></li>
<li><%= link_to "Delete", "#" %></li>
<% end %>
<li><%= link_to "Add to Pool", "#" %></li>
</menu>
</section>
</aside>
<section>
<h1>Post</h1>
<section>
<h2>Image</h2>
<%= @post.presenter.image_html %>
</section>
<section>
<h2>Notes</h2>
<%= @post.presenter.note_html %>
</section>
<section>
<h2>Comments</h2>
</section>
<section>
<h2>Edit</h2>
</section>
</section>
<% content_for(:page_title) do %>
/ <%= @post.tag_string %>
<% end %>
<% content_for(:html_header) do %>
<meta name="tags" content="<%= @post.tag_string %>">
<meta name="favorites" content="<%= @post.fav_string %>">
<meta name="pools" content="<%= @post.pool_string %>">
<% end %>
<%= render :partial => "posts/common_secondary_nav_links" %>

View File

@@ -0,0 +1,24 @@
<table width="100%">
<thead>
<tr>
<th></th>
<th>Uploader</th>
<th>Status</th>
<th>Date</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
<% @uploads.each do |upload| %>
<tr>
<td><%= link_to upload.id, upload_path(upload) %></td>
<td><%= link_to upload.uploader.name, user_path(upload.uploader) %></td>
<td><%= upload.presenter.status(self) %></td>
<td><%= upload.created_at %></td>
<td><%= upload.tag_string %></td>
</tr>
<% end %>
</tbody>
</table>
<%= render :partial => "posts/common_secondary_nav_links" %>

View File

@@ -52,3 +52,5 @@
<% content_for(:page_title) do %>
/ Upload
<% end %>
<%= render :partial => "posts/common_secondary_nav_links" %>

View File

@@ -13,3 +13,7 @@
<% else %>
<p>An error occurred: <%= @upload.status %></p>
<% end %>
<p>You can <%= link_to "upload another file", new_upload_path %> or <%= link_to "view your current uploads", uploads_path %>.</p>
<%= render :partial => "posts/common_secondary_nav_links" %>

View File

@@ -186,5 +186,10 @@ module Danbooru
</script>
}.html_safe
end
# The number of posts displayed per page.
def posts_per_page
20
end
end
end

View File

@@ -4,5 +4,9 @@ module Danbooru
def app_name
"f"
end
def posts_per_page
1
end
end
end

View File

@@ -20,6 +20,7 @@ Danbooru::Application.routes.draw do |map|
resources :janitor_trials
resources :jobs
resources :notes
resources :note_versions
resources :pools do
member do
put :revert

View File

@@ -1,19 +1,4 @@
module Cache
def expire(options = {})
tags = options[:tags]
cache_version = Cache.get("$cache_version").to_i
Cache.put("$cache_version", cache_version + 1)
if tags
tags.scan(/\S+/).each do |x|
key = "tag:#{x}"
key_version = Cache.get(key).to_i
Cache.put(key, key_version + 1)
end
end
end
def incr(key, expiry = 0)
val = Cache.get(key, expiry)
Cache.put(key, val.to_i + 1)
@@ -98,7 +83,6 @@ module Cache
module_function :get
module_function :get_multi
module_function :expire
module_function :incr
module_function :put
module_function :delete