diff --git a/Gemfile b/Gemfile
index be35d7741..73787f0a6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -17,5 +17,6 @@ gem "haml"
gem "simple_form"
gem "mechanize"
gem "nokogiri"
+gem "meta_search"
gem "will_paginate", :git => "http://github.com/mislav/will_paginate.git", :branch => "rails3"
diff --git a/Gemfile.lock b/Gemfile.lock
index 1da923683..d0c7ec7fa 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -61,6 +61,11 @@ GEM
mechanize (1.0.0)
nokogiri (>= 1.2.1)
memcache-client (1.8.5)
+ meta_search (0.9.7.2)
+ actionpack (~> 3.0.0)
+ activerecord (~> 3.0.0)
+ activesupport (~> 3.0.0)
+ arel (~> 1.0.1)
mime-types (1.16)
mocha (0.9.9)
rake
@@ -107,6 +112,7 @@ DEPENDENCIES
imagesize
mechanize
memcache-client
+ meta_search
mocha
nokogiri
pg
diff --git a/app/controllers/post_histories_controller.rb b/app/controllers/post_histories_controller.rb
new file mode 100644
index 000000000..0d99079d9
--- /dev/null
+++ b/app/controllers/post_histories_controller.rb
@@ -0,0 +1,6 @@
+class PostHistoriesController < ApplicationController
+ def index
+ @search = PostHistory.search(params[:search])
+ @histories = @search.paginate(:page => params[:page], :per_page => 20)
+ end
+end
diff --git a/app/controllers/post_versions_controller.rb b/app/controllers/post_versions_controller.rb
deleted file mode 100644
index 7ceb99fec..000000000
--- a/app/controllers/post_versions_controller.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-class PostVersionsController < ApplicationController
- def index
- end
-end
diff --git a/app/models/post_history.rb b/app/models/post_history.rb
index 2aac39eea..0b2059daf 100644
--- a/app/models/post_history.rb
+++ b/app/models/post_history.rb
@@ -1,5 +1,60 @@
class PostHistory < ActiveRecord::Base
class Error < Exception ; end
+
+ class Revision
+ attr_accessor :prev, :hash, :diff, :tag_array
+
+ def initialize(hash)
+ @hash = hash
+ @diff = {}
+ @tag_array = Tag.scan_tags(@hash["tag_string"])
+ end
+
+ def calculate_diff
+ if prev.nil?
+ diff[:add] = tag_array
+ diff[:del] = []
+ diff[:rating] = rating
+ diff[:source] = source
+ diff[:parent_id] = parent_id
+ else
+ diff[:del] = prev.tag_array - tag_array
+ diff[:add] = tag_array - prev.tag_array
+
+ if prev.rating != rating
+ diff[:rating] = rating
+ end
+
+ if prev.source != source
+ diff[:source] = source
+ end
+
+ if prev.parent_id != parent_id
+ diff[:parent_id]= parent_id
+ end
+ end
+ end
+
+ def rating
+ hash["rating"]
+ end
+
+ def source
+ hash["source"]
+ end
+
+ def parent_id
+ hash["parent_id"]
+ end
+
+ def updated_at
+ hash["updated_at"]
+ end
+
+ def updater_id
+ hash["user_id"]
+ end
+ end
before_validation :initialize_revisions, :on => :create
belongs_to :post
@@ -37,4 +92,19 @@ class PostHistory < ActiveRecord::Base
write_attribute(:revisions, (revisions << revision).to_json)
save
end
+
+ def each_revision(&block)
+ array = revisions.map {|x| Revision.new(x)}
+ link_revisions(array)
+ array.each {|x| x.calculate_diff}
+ array.each(&block)
+ end
+
+ private
+ def link_revisions(array)
+ 1.upto(array.size - 1) do |i|
+ array[i].prev = array[i - 1]
+ end
+ end
+
end
diff --git a/app/presenters/post_history_presenter.rb b/app/presenters/post_history_presenter.rb
new file mode 100644
index 000000000..89c30c29e
--- /dev/null
+++ b/app/presenters/post_history_presenter.rb
@@ -0,0 +1,19 @@
+class PostHistoryPresenter < Presenter
+ attr_reader :revision
+
+ def initialize(revision)
+ @revision = revision
+ end
+
+ def changes
+
+ end
+
+ def updated_at
+ revision["updated_at"]
+ end
+
+ def updater_name
+ User.id_to_name(revision["user_id"].to_i)
+ end
+end
diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb
index 89eca855a..44f372c76 100644
--- a/app/presenters/post_presenter.rb
+++ b/app/presenters/post_presenter.rb
@@ -1,7 +1,24 @@
class PostPresenter < Presenter
+ def self.preview(post)
+ flags = []
+ flags << "pending" if post.is_pending?
+ flags << "flagged" if post.is_flagged?
+ flags << "removed" if post.is_removed?
+
+ html = %{}
+ html << %{}
+ html << %{
}
+ html << %{}
+ html << %{}
+ end
+
def initialize(post)
@post = post
end
+
+ def preview_html
+ PostPresenter.preview(@post)
+ end
def image_html(template)
return template.content_tag("p", "This image was deleted.") if @post.is_removed? && !CurrentUser.user.is_janitor?
diff --git a/app/presenters/post_set_presenter.rb b/app/presenters/post_set_presenter.rb
index ec2aa1305..2ab3f9968 100644
--- a/app/presenters/post_set_presenter.rb
+++ b/app/presenters/post_set_presenter.rb
@@ -50,16 +50,7 @@ class PostSetPresenter < Presenter
html = ""
posts.each do |post|
- flags = []
- flags << "pending" if post.is_pending?
- flags << "flagged" if post.is_flagged?
- flags << "removed" if post.is_removed?
-
- html << %{}
- html << %{}
- html << %{
}
- html << %{}
- html << %{}
+ html << PostPresenter.preview(post)
end
html.html_safe
diff --git a/app/views/post_histories/index.html.erb b/app/views/post_histories/index.html.erb
new file mode 100644
index 000000000..3d52de02e
--- /dev/null
+++ b/app/views/post_histories/index.html.erb
@@ -0,0 +1,35 @@
+
+
+
Post History
+
+ <% @histories.each do |history| %>
+
+
+ <%= history.post.presenter.preview_html %>
+
+
+
+
+
+
+ | Changes |
+ Date |
+ Updater |
+
+
+
+ <% history.each_revision do |revision| %>
+
+ | <%= revision.presenter.changes %> |
+ <%= revision.presenter.updated_at %> |
+ <%= revision.presenter.updater_name %> |
+
+ <% end %>
+
+
+
+
+ <% end %>
+
+
+
diff --git a/config/routes.rb b/config/routes.rb
index 5181ff0c9..604083302 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -39,7 +39,7 @@ Danbooru::Application.routes.draw do
end
end
resources :post_moderation_details
- resources :post_versions
+ resources :post_histories
resources :post_votes
resources :reports
resources :sessions
diff --git a/test/unit/post_history_test.rb b/test/unit/post_history_test.rb
index 18c678aaf..40d5dd90a 100644
--- a/test/unit/post_history_test.rb
+++ b/test/unit/post_history_test.rb
@@ -7,6 +7,7 @@ class PostHistoryTest < ActiveSupport::TestCase
CurrentUser.user = @user
CurrentUser.ip_addr = "127.0.0.1"
MEMCACHE.flush_all
+ PostHistory.stubs(:revision_time).returns("TIME")
end
teardown do
@@ -15,19 +16,48 @@ class PostHistoryTest < ActiveSupport::TestCase
end
should "create a revision after creation" do
- PostHistory.stubs(:revision_time).returns("TIME")
post = Factory.create(:post, :tag_string => "aaa bbb ccc")
assert_equal(1, post.revisions.size)
- assert_equal({"source"=>nil, "rating"=>"q", "tag_string"=>"aaa bbb ccc", "parent_id"=>nil, "user_id"=>1, "ip_addr"=>"127.0.0.1", "updated_at"=>"TIME"}, post.revisions.last)
+ assert_equal({"source"=>nil, "rating"=>"q", "tag_string"=>"aaa bbb ccc", "parent_id"=>nil, "user_id"=>@user.id, "ip_addr"=>"127.0.0.1", "updated_at"=>"TIME"}, post.revisions.last)
end
should "create additional revisions after updating" do
- PostHistory.stubs(:revision_time).returns("TIME")
post = Factory.create(:post, :tag_string => "aaa bbb ccc")
post.update_attributes(:tag_string => "bbb ccc ddd")
post.reload
assert_equal(2, post.revisions.size)
- assert_equal({"source"=>nil, "rating"=>"q", "tag_string"=>"bbb ccc ddd", "parent_id"=>nil, "user_id"=>3, "ip_addr"=>"127.0.0.1", "updated_at"=>"TIME"}, post.revisions.last)
+ assert_equal({"source"=>nil, "rating"=>"q", "tag_string"=>"bbb ccc ddd", "parent_id"=>nil, "user_id"=>@user.id, "ip_addr"=>"127.0.0.1", "updated_at"=>"TIME"}, post.revisions.last)
+ end
+
+ context "history" do
+ setup do
+ @post = Factory.create(:post, :tag_string => "aaa bbb ccc", :source => "xyz", :rating => "q")
+ @post.update_attributes(:tag_string => "bbb ccc ddd", :source => "abc", :rating => "s")
+ @post.update_attributes(:tag_string => "ccc ddd eee")
+ @revisions = []
+ @post.history.each_revision do |revision|
+ @revisions << revision
+ end
+ end
+
+ should "link revisions together" do
+ assert_nil(@revisions[0].prev)
+ assert_equal(@revisions[0], @revisions[1].prev)
+ assert_equal(@revisions[1], @revisions[2].prev)
+ end
+
+ should "iterate over its revisions" do
+ assert_equal(3, @revisions.size)
+ assert_equal(%w(aaa bbb ccc), @revisions[0].tag_array)
+ assert_equal(%w(bbb ccc ddd), @revisions[1].tag_array)
+ assert_equal(%w(ccc ddd eee), @revisions[2].tag_array)
+ end
+
+ should "create a diff for each revision detailing what changed" do
+ assert_equal({:add=>["aaa", "bbb", "ccc"], :del=>[], :rating=>"q", :source=>"xyz", :parent_id=>nil}, @revisions[0].diff)
+ assert_equal({:del=>["aaa"], :add=>["ddd"], :rating=>"s", :source=>"abc"}, @revisions[1].diff)
+ assert_equal({:del=>["bbb"], :add=>["eee"]}, @revisions[2].diff)
+ end
end
end
end