add wiki diff

This commit is contained in:
albert
2013-02-23 20:08:20 -05:00
parent 586c9a7258
commit 81c9ba22a7
9 changed files with 125 additions and 29 deletions

View File

@@ -31,6 +31,7 @@ gem 'net-ssh'
gem 'net-sftp'
gem 'newrelic_rpm'
gem 'term-ansicolor', :require => "term/ansicolor"
gem 'diff-lcs', :require => "diff/lcs/array"
group :development do
gem 'ruby-prof'

View File

@@ -66,6 +66,7 @@ GEM
delayed_job_active_record (0.4.1)
activerecord (>= 2.1.0, < 4)
delayed_job (~> 3.0)
diff-lcs (1.2.1)
domain_name (0.5.7)
unf (~> 0.0.3)
erubis (2.7.0)
@@ -188,6 +189,7 @@ DEPENDENCIES
daemons
delayed_job
delayed_job_active_record
diff-lcs
factory_girl
ffaker!
mechanize!

View File

@@ -7,4 +7,18 @@ div#c-wiki-pages {
float: left;
width: 30em;
}
del {
background: #FCC;
text-decoration: none;
}
ins {
background: #CFC;
text-decoration: none;
}
table {
margin-bottom: 1em;
}
}

View File

@@ -10,4 +10,9 @@ class WikiPageVersionsController < ApplicationController
@wiki_page_version = WikiPageVersion.find(params[:id])
respond_with(@wiki_page_version)
end
def diff
@thispage = WikiPageVersion.find(params[:thispage])
@otherpage = WikiPageVersion.find(params[:otherpage])
end
end

View File

@@ -1,2 +1,51 @@
module WikiPageVersionsHelper
def wiki_page_diff(thispage, otherpage)
pattern = Regexp.new('(?:<.+?>)|(?:\w+)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)')
thisarr = thispage.body.scan(pattern)
otharr = otherpage.body.scan(pattern)
cbo = Diff::LCS::ContextDiffCallbacks.new
diffs = thisarr.diff(otharr, cbo)
escape_html = lambda {|str| str.gsub(/&/,'&amp;').gsub(/</,'&lt;').gsub(/>/,'&gt;')}
output = thisarr
output.each { |q| q.replace(escape_html[q]) }
diffs.reverse_each do |hunk|
newchange = hunk.max{|a,b| a.old_position <=> b.old_position}
newstart = newchange.old_position
oldstart = hunk.min{|a,b| a.old_position <=> b.old_position}.old_position
if newchange.action == '+'
output.insert(newstart, '</ins>')
end
hunk.reverse_each do |chg|
case chg.action
when '-'
oldstart = chg.old_position
output[chg.old_position] = '<br>' if chg.old_element.match(/^\r?\n$/)
when '+'
if chg.new_element.match(/^\r?\n$/)
output.insert(chg.old_position, '<br>')
else
output.insert(chg.old_position, "#{escape_html[chg.new_element]}")
end
end
end
if newchange.action == '+'
output.insert(newstart, '<ins>')
end
if hunk[0].action == '-'
output.insert((newstart == oldstart || newchange.action != '+') ? newstart+1 : newstart, '</del>')
output.insert(oldstart, '<del>')
end
end
output.join.gsub(/\r?\n/, '<br>').html_safe
end
end

View File

@@ -24,7 +24,7 @@ class WikiPageVersion < ActiveRecord::Base
end
extend SearchMethods
def updater_name
User.id_to_name(updater_id)
end

View File

@@ -0,0 +1,13 @@
<div id="c-wiki-pages">
<div id="a-diff">
<h1>Wiki Page: <%= @thispage.title %></h1>
<p>Showing differences between <%= compact_time @thispage.created_at %> (<%= link_to @thispage.updater.name, user_path(@thispage.updater) %>) and <%= compact_time @otherpage.created_at %> (<%= link_to @otherpage.updater.name, user_path(@otherpage.updater) %>)</p>
<div>
<%= wiki_page_diff(@thispage, @otherpage) %>
</div>
</div>
</div>
<%= render "wiki_pages/secondary_links" %>

View File

@@ -5,34 +5,42 @@
<section id="content">
<h1>Wiki Pages</h1>
<table width="100%" class="striped">
<thead>
<tr>
<th width="60%">Title</th>
<th width="10%">IP Address</th>
<th width="30%">Last edited</th>
</tr>
</thead>
<tbody>
<% @wiki_page_versions.each do |wiki_page_version| %>
<%= form_tag(diff_wiki_page_versions_path, :method => :get) do %>
<table width="100%" class="striped">
<thead>
<tr>
<td><%= wiki_page_version.title %></td>
<td>
<% if CurrentUser.is_admin? %>
<%= wiki_page_version.updater_ip_addr %>
<% end %>
</td>
<td>
<%= link_to wiki_page_version.updated_at.strftime("%Y-%m-%d %I:%M"), wiki_page_version_path(wiki_page_version) %>
<% if wiki_page_version.updater %>
by
<%= link_to wiki_page_version.updater_name, user_path(wiki_page_version.updater) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<th width="2%"></th>
<th width="2%"></th>
<th width="60%">Title</th>
<th width="10%">IP Address</th>
<th width="26%">Last edited</th>
</tr>
</thead>
<tbody>
<% @wiki_page_versions.each do |wiki_page_version| %>
<tr>
<td><%= radio_button_tag "thispage", wiki_page_version.id %></td>
<td><%= radio_button_tag "otherpage", wiki_page_version.id %></td>
<td><%= wiki_page_version.title %></td>
<td>
<% if CurrentUser.is_admin? %>
<%= wiki_page_version.updater_ip_addr %>
<% end %>
</td>
<td>
<%= link_to wiki_page_version.updated_at.strftime("%Y-%m-%d %I:%M"), wiki_page_version_path(wiki_page_version) %>
<% if wiki_page_version.updater %>
by
<%= link_to wiki_page_version.updater_name, user_path(wiki_page_version.updater) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Diff" %>
<% end %>
<%= numbered_paginator(@wiki_page_versions) %>
</section>

View File

@@ -193,7 +193,11 @@ Danbooru::Application.routes.draw do
get :show_or_new
end
end
resources :wiki_page_versions, :only => [:index, :show]
resources :wiki_page_versions, :only => [:index, :show, :diff] do
collection do
get :diff
end
end
# aliases
resources :wpages, :controller => "wiki_pages"