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 %> +
+ +
+ + + + + + + + + + <% history.each_revision do |revision| %> + + + + + + <% end %> + +
ChangesDateUpdater
<%= revision.presenter.changes %><%= revision.presenter.updated_at %><%= revision.presenter.updater_name %>
+
+
+ <% 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