From 052754b068aedca032de5a72d570cbc0913fc061 Mon Sep 17 00:00:00 2001 From: Alexey Verkhovsky Date: Sun, 14 Aug 2005 22:26:54 +0000 Subject: [PATCH] Dropped number from revision table. Also dropped timestamp. We will rely on autoincremented ID for sorting, and will for now store the time of last edit of the revision in revised_at. Later we will refactor content into a separate table (so as not to load the whole 300 kb of text and cached HTML every time we need page.revisions in code). Rake tests all pass, but watir tests indicate that some revision traversing links are still broken --- app/controllers/wiki_controller.rb | 9 ++--- app/models/page.rb | 44 ++++++++++++++++--------- app/models/page_set.rb | 5 ++- app/models/revision.rb | 43 ++++++++---------------- app/models/web.rb | 4 +-- app/models/wiki.rb | 4 +-- app/views/wiki/page.rhtml | 4 +-- app/views/wiki/print.rhtml | 2 +- app/views/wiki/recently_revised.rhtml | 2 +- app/views/wiki/revision.rhtml | 26 +++++++-------- app/views/wiki/rollback.rhtml | 2 +- app/views/wiki/rss_feed.rhtml | 2 +- db/revisions.erbsql | 10 ++++-- test/fixtures/revisions.yml | 27 +++++---------- test/functional/wiki_controller_test.rb | 4 +-- test/unit/page_test.rb | 32 +++++++++++------- test/unit/revision_test.rb | 6 ++-- test/watir/e2e.rb | 2 +- 18 files changed, 116 insertions(+), 112 deletions(-) diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index c274e209..3e43eaf6 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -140,7 +140,7 @@ class WikiController < ApplicationController def pdf page = wiki.read_page(@web_name, @page_name) safe_page_name = @page.name.gsub(/\W/, '') - file_name = "#{safe_page_name}-#{@web.address}-#{@page.created_at.strftime('%Y-%m-%d-%H-%M-%S')}" + file_name = "#{safe_page_name}-#{@web.address}-#{@page.revised_on.strftime('%Y-%m-%d-%H-%M-%S')}" file_path = File.join(@wiki.storage_path, file_name) export_page_to_tex("#{file_path}.tex") unless FileTest.exists?("#{file_path}.tex") @@ -274,7 +274,8 @@ class WikiController < ApplicationController end def get_page_and_revision - @revision = @page.revisions[@params['rev'].to_i] + @revision_number = @params['rev'].to_i + @revision = @page.revisions[@revision_number] end def parse_category @@ -312,8 +313,8 @@ class WikiController < ApplicationController @pages_by_revision = @web.select.by_revision.first(limit) else @pages_by_revision = @web.select.by_revision - @pages_by_revision.reject! { |page| page.created_at < start_date } if start_date - @pages_by_revision.reject! { |page| page.created_at > end_date } if end_date + @pages_by_revision.reject! { |page| page.revised_on < start_date } if start_date + @pages_by_revision.reject! { |page| page.revised_on > end_date } if end_date end @hide_description = hide_description diff --git a/app/models/page.rb b/app/models/page.rb index 6baa5802..97f11879 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -1,9 +1,9 @@ class Page < ActiveRecord::Base belongs_to :web - has_many :revisions, :order => 'number' - has_one :current_revision, :class_name => 'Revision', :order => 'number DESC' + has_many :revisions, :order => 'id' + has_one :current_revision, :class_name => 'Revision', :order => 'id DESC' - def revise(content, created_at, author) + def revise(content, time, author) revisions_size = new_record? ? 0 : revisions.size if (revisions_size > 0) and content == current_revision.content raise Instiki::ValidationError.new( @@ -13,37 +13,49 @@ class Page < ActiveRecord::Base author = Author.new(author.to_s) unless author.is_a?(Author) # Try to render content to make sure that markup engine can take it, - # before addin a revision to the page - Revision.new(:page => self, :content => content, :created_at => created_at, :author => author).force_rendering + Revision.new(:page => self, :content => content, :author => author, :revised_at => time).force_rendering # A user may change a page, look at it and make some more changes - several times. # Not to record every such iteration as a new revision, if the previous revision was done # by the same author, not more than 30 minutes ago, then update the last revision instead of # creating a new one - if (revisions_size > 0) && continous_revision?(created_at, author) - current_revision.update_attributes(:created_at => created_at, :content => content) + if (revisions_size > 1) && continous_revision?(time, author) + current_revision.update_attributes(:content => content, :revised_at => time) else - Revision.create(:page => self, :content => content, :created_at => created_at, :author => author) + Revision.create(:page => self, :content => content, :author => author, :revised_at => time) end - self.created_at = created_at save web.refresh_pages_with_references(name) if revisions_size == 0 self end - def rollback(revision_number, created_at, author_ip = nil) - roll_back_revision = Revision.find(:first, :conditions => ['page_id = ? AND number = ?', id, revision_number]) - revise(roll_back_revision.content, created_at, Author.new(roll_back_revision.author, author_ip)) + def rollback(revision_number, time, author_ip = nil) + roll_back_revision = self.revisions[revision_number] + if roll_back_revision.nil? + raise Instiki::ValidationError.new("Revision #{revision_number} not found") + end + revise(roll_back_revision.content, time, Author.new(roll_back_revision.author, author_ip)) end def revisions? revisions.size > 1 end - def revised_on - created_on + def previous_revision(revision) + revision_index = revisions.each_with_index do |rev, index| + if rev.id == revision.id + break index + else + nil + end + end + if revision_index.nil? or revision_index == 0 + nil + else + revisions[revision_index - 1] + end end def in_category?(cat) @@ -108,8 +120,8 @@ class Page < ActiveRecord::Base private - def continous_revision?(created_at, author) - current_revision.author == author && current_revision.created_at + 30.minutes > created_at + def continous_revision?(time, author) + (current_revision.author == author) && (revised_on + 30.minutes > time) end # Forward method calls to the current revision, so the page responds to all revision calls diff --git a/app/models/page_set.rb b/app/models/page_set.rb index c50abe80..47e1d4e9 100644 --- a/app/models/page_set.rb +++ b/app/models/page_set.rb @@ -17,10 +17,9 @@ class PageSet < Array end def most_recent_revision - self.map { |page| page.created_at }.max || Time.at(0) + self.map { |page| page.revised_on }.max || Time.at(0) end - def by_name PageSet.new(@web, sort_by { |page| page.name }) end @@ -28,7 +27,7 @@ class PageSet < Array alias :sort :by_name def by_revision - PageSet.new(@web, sort_by { |page| page.created_at }).reverse + PageSet.new(@web, sort_by { |page| page.revised_on }).reverse end def pages_that_reference(page_name) diff --git a/app/models/revision.rb b/app/models/revision.rb index 9d2c0ba1..9eecbcf1 100644 --- a/app/models/revision.rb +++ b/app/models/revision.rb @@ -3,24 +3,13 @@ class Revision < ActiveRecord::Base belongs_to :page composed_of :author, :mapping => [ %w(author name), %w(ip ip) ] - def created_on - created_at.to_date + def revised_on + revised_at end - def pretty_created_at - # Must use DateTime because Time doesn't support %e on at least some platforms - DateTime.new( - created_at.year, created_at.mon, created_at.day, created_at.hour, created_at.min - ).strftime "%B %e, %Y %H:%M" - end - - # todo: drop next_revision, previuous_revision and number from here - unused code - def next_revision - Revision.find_by_number_and_page_id(number+1, page_id) - end - - def previous_revision - @previous_revions ||= number > 0 ? Revision.find_by_number_and_page_id(number-1, page_id) : nil + # TODO this method belongs in the view helpers (only views use it) + def pretty_created_on + revised_on.to_date.strftime "%B %e, %Y %H:%M:%S" end # Returns an array of all the WikiIncludes present in the content of this revision. @@ -30,7 +19,7 @@ class Revision < ActiveRecord::Base @wiki_includes_cache = chunks.map { |c| ( c.escaped? ? nil : c.page_name ) }.compact.uniq end @wiki_includes_cache - end + end # Returns an array of all the WikiReferences present in the content of this revision. def wiki_references @@ -72,8 +61,14 @@ class Revision < ActiveRecord::Base @display_cache end + # TODO this probably doesn't belong in revision (because it has to call back the page) def display_diff - previous_revision ? HTMLDiff.diff(previous_revision.display_content, display_content) : display_content + previous_revision = page.previous_revision(self) + if previous_revision + HTMLDiff.diff(previous_revision.display_content, display_content) + else + display_content + end end def clear_display_cache @@ -112,18 +107,8 @@ class Revision < ActiveRecord::Base end protected - before_create :set_revision_number, :set_timestamp + after_create :force_rendering after_save :clear_display_cache - - # TODO Refactor this away. Revisions collection should not rely on the revision number for - # sorting etc - revisions must be easy to delete (this helps fighting wiki spam) - def set_revision_number - self.number = self.class.count(['page_id = ?', page_id]) + 1 - end - - def set_timestamp - self.timestamp = (Time.now.to_f * 1000).to_i.to_s - end end diff --git a/app/models/web.rb b/app/models/web.rb index 5ca077d5..a568e6a1 100644 --- a/app/models/web.rb +++ b/app/models/web.rb @@ -17,9 +17,9 @@ class Web < ActiveRecord::Base self.brackets_only != brackets_only end - def add_page(name, content, created_at, author) + def add_page(name, content, time, author) page = page(name) || Page.new(:web => self, :name => name) - page.revise(content, created_at, author) + page.revise(content, time, author) end def authors diff --git a/app/models/wiki.rb b/app/models/wiki.rb index 50093193..e1390e31 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -64,9 +64,9 @@ class Wiki page.revise(content, revised_on, author) end - def rollback_page(web_address, page_name, revision_number, created_at, author_id = nil) + def rollback_page(web_address, page_name, revision_number, time, author_id = nil) page = read_page(web_address, page_name) - page.rollback(revision_number, created_at, author_id) + page.rollback(revision_number, time, author_id) end def setup(password, web_name, web_address) diff --git a/app/views/wiki/page.rhtml b/app/views/wiki/page.rhtml index 28763b78..a48cb7c3 100644 --- a/app/views/wiki/page.rhtml +++ b/app/views/wiki/page.rhtml @@ -12,7 +12,7 @@