added wiki page

This commit is contained in:
albert
2010-02-15 17:32:32 -05:00
parent e745a87e5f
commit 80f033f253
9 changed files with 247 additions and 6 deletions

View File

@@ -11,7 +11,7 @@ class Artist < ActiveRecord::Base
has_one :wiki_page, :foreign_key => "title", :primary_key => "name"
has_one :tag_alias, :foreign_key => "antecedent_name", :primary_key => "name"
accepts_nested_attributes_for :wiki_page
attr_accessible :url_string, :other_names, :group_name, :wiki_page_attributes
attr_accessible :name, :url_string, :other_names, :group_name, :wiki_page_attributes
module UrlMethods
module ClassMethods

View File

@@ -7,6 +7,7 @@ class Pool < ActiveRecord::Base
belongs_to :updater, :class_name => "User"
has_many :versions, :class_name => "PoolVersion", :dependent => :destroy
after_save :create_version
attr_accessible :name, :description, :post_ids, :is_public, :is_active
def self.create_anonymous(creator, creator_ip_addr)
pool = Pool.create(:name => "TEMP:#{Time.now.to_f}.#{rand(1_000_000)}", :creator => creator, :updater_id => creator.id, :updater_ip_addr => creator_ip_addr)

View File

@@ -1,3 +1,61 @@
class WikiPage < ActiveRecord::Base
attr_accessor :updater_id, :updater_ip_addr
before_save :normalize_title
after_save :create_version
belongs_to :creator, :class_name => "User"
belongs_to :updater, :class_name => "User"
validates_uniqueness_of :title, :case_sensitive => false
validates_presence_of :body, :updater_id, :updater_ip_addr
attr_protected :text_search_index, :is_locked, :version
scope :titled, lambda {|title| where(["title = ?", title.downcase.tr(" ", "_")])}
has_one :tag, :foreign_key => "name", :primary_key => "title"
has_one :artist, :foreign_key => "name", :primary_key => "title"
has_many :versions, :class_name => "WikiPageVersion"
def self.build_relation(options = {})
relation = where()
if options[:title]
relation = relation.where(["title LIKE ? ESCAPE E'\\\\'", options[:title].downcase.tr(" ", "_").to_escaped_for_sql_like])
end
if options[:creator_id]
relation = relation.where(["creator_id = ?", options[:creator_id]])
end
relation
end
def revert_to(version)
self.title = version.title
self.body = version.body
self.is_locked = version.is_locked
end
def revert_to!(version)
revert_to(version)
save!
end
def normalize_title
self.title = title.downcase.tr(" ", "_")
end
def creator_name
User.find_name(user_id).tr("_", " ")
end
def pretty_title
title.tr("_", " ")
end
def create_version
versions.create(
:updater_id => updater_id,
:updater_ip_addr => updater_ip_addr,
:title => title,
:body => body,
:is_locked => is_locked
)
end
end

View File

@@ -0,0 +1,12 @@
class WikiPageVersion < ActiveRecord::Base
belongs_to :wiki_page
belongs_to :updater
def updater_name
User.find_name(updater_id)
end
def pretty_title
title.tr("_", " ")
end
end

View File

@@ -0,0 +1,53 @@
class WikiPagePresenter
# Produce a formatted page that shows the difference between two versions of a page.
def diff(other_version)
pattern = Regexp.new('(?:<.+?>)|(?:[0-9_A-Za-z\x80-\xff]+[\x09\x20]?)|(?:[ \t]+)|(?:\r?\n)|(?:.+?)')
thisarr = self.body.scan(pattern)
otharr = other_version.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(CGI.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] = "" if chg.old_element.match(/^\r?\n$/)
when '+'
if chg.new_element.match(/^\r?\n$/)
output.insert(chg.old_position, "[nl]")
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/, "[nl]")
end
end

View File

@@ -948,6 +948,42 @@ CREATE SEQUENCE users_id_seq
ALTER SEQUENCE users_id_seq OWNED BY users.id;
--
-- Name: wiki_page_versions; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE wiki_page_versions (
id integer NOT NULL,
wiki_page_id integer NOT NULL,
updater_id integer NOT NULL,
updater_ip_addr inet NOT NULL,
title character varying(255) NOT NULL,
body text NOT NULL,
is_locked boolean NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone
);
--
-- Name: wiki_page_versions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE wiki_page_versions_id_seq
START WITH 1
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
--
-- Name: wiki_page_versions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE wiki_page_versions_id_seq OWNED BY wiki_page_versions.id;
--
-- Name: wiki_pages; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@@ -1158,6 +1194,13 @@ ALTER TABLE uploads ALTER COLUMN id SET DEFAULT nextval('uploads_id_seq'::regcla
ALTER TABLE users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE wiki_page_versions ALTER COLUMN id SET DEFAULT nextval('wiki_page_versions_id_seq'::regclass);
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -1365,6 +1408,14 @@ ALTER TABLE ONLY users
ADD CONSTRAINT users_pkey PRIMARY KEY (id);
--
-- Name: wiki_page_versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY wiki_page_versions
ADD CONSTRAINT wiki_page_versions_pkey PRIMARY KEY (id);
--
-- Name: wiki_pages_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@@ -1758,6 +1809,13 @@ CREATE UNIQUE INDEX index_users_on_email ON users USING btree (email);
CREATE UNIQUE INDEX index_users_on_name ON users USING btree (lower((name)::text));
--
-- Name: index_wiki_page_versions_on_wiki_page_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
CREATE INDEX index_wiki_page_versions_on_wiki_page_id ON wiki_page_versions USING btree (wiki_page_id);
--
-- Name: index_wiki_pages_on_body_index_index; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@@ -1853,4 +1911,6 @@ INSERT INTO schema_migrations (version) VALUES ('20100214080557');
INSERT INTO schema_migrations (version) VALUES ('20100214080605');
INSERT INTO schema_migrations (version) VALUES ('20100215182234');
INSERT INTO schema_migrations (version) VALUES ('20100215182234');
INSERT INTO schema_migrations (version) VALUES ('20100215213756');

View File

@@ -0,0 +1,19 @@
class CreateWikiPageVersions < ActiveRecord::Migration
def self.up
create_table :wiki_page_versions do |t|
t.column :wiki_page_id, :integer, :null => false
t.column :updater_id, :integer, :null => false
t.column :updater_ip_addr, "inet", :null => false
t.column :title, :string, :null => false
t.column :body, :text, :null => false
t.column :is_locked, :boolean, :null => false
t.timestamps
end
add_index :wiki_page_versions, :wiki_page_id
end
def self.down
drop_table :wiki_page_versions
end
end

View File

@@ -0,0 +1,7 @@
Factory.define(:wiki_page) do |f|
f.creator {|x| x.association(:user)}
f.title {|x| Faker::Lorem.words}
f.body {Faker::Lorem.sentences}
f.updater_id {|x| x.creator_id}
f.updater_ip_addr "127.0.0.1"
end

View File

@@ -1,8 +1,39 @@
require 'test_helper'
require File.dirname(__FILE__) + '/../test_helper'
class WikiPageTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
context "A wiki page" do
setup do
MEMCACHE.flush_all
end
should "normalize its title" do
wp = Factory.create(:wiki_page, :title => "HOT POTATO")
assert_equal("hot_potato", wp.title)
end
should "search by title" do
Factory.create(:wiki_page, :title => "HOT POTATO")
matches = WikiPage.titled("hot potato")
assert_equal(1, matches.count)
assert_equal("hot_potato", matches.first.title)
end
should "create versions" do
wp = nil
user = Factory.create(:user)
assert_difference("WikiPageVersion.count") do
wp = Factory.create(:wiki_page, :title => "xxx")
end
assert_difference("WikiPageVersion.count") do
wp.update_attributes(:title => "yyy", :updater_id => user.id, :updater_ip_addr => "127.0.0.1")
end
version = WikiPageVersion.first
wp.revert_to!(version)
assert_equal("xxx", wp.title)
end
end
end