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 @@