irwi_mod 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +12 -0
- data/app/views/base_wiki_pages/_wiki_page_actions.html.erb +5 -0
- data/app/views/base_wiki_pages/_wiki_page_history.html.erb +31 -0
- data/app/views/base_wiki_pages/_wiki_page_info.html.erb +3 -0
- data/app/views/base_wiki_pages/_wiki_page_style.html.erb +69 -0
- data/app/views/base_wiki_pages/all.html.erb +11 -0
- data/app/views/base_wiki_pages/compare.html.erb +15 -0
- data/app/views/base_wiki_pages/edit.html.erb +36 -0
- data/app/views/base_wiki_pages/history.html.erb +8 -0
- data/app/views/base_wiki_pages/index.html.erb +11 -0
- data/app/views/base_wiki_pages/new.html.erb +14 -0
- data/app/views/base_wiki_pages/no.html.erb +1 -0
- data/app/views/base_wiki_pages/not_allowed.html.erb +1 -0
- data/app/views/base_wiki_pages/show.html.erb +11 -0
- data/lib/generators/irwi_wiki/irwi_wiki_generator.rb +29 -0
- data/lib/generators/irwi_wiki/templates/controllers/wiki_pages_controller.rb +5 -0
- data/lib/generators/irwi_wiki/templates/helpers/wiki_pages_helper.rb +3 -0
- data/lib/generators/irwi_wiki/templates/migrate/create_wiki_pages.rb +44 -0
- data/lib/generators/irwi_wiki/templates/models/wiki_page.rb +5 -0
- data/lib/generators/irwi_wiki/templates/models/wiki_page_version.rb +5 -0
- data/lib/generators/irwi_wiki_attachments/irwi_wiki_attachments_generator.rb +22 -0
- data/lib/generators/irwi_wiki_attachments/templates/migrate/create_wiki_page_attachments.rb +19 -0
- data/lib/generators/irwi_wiki_attachments/templates/models/wiki_page_attachment.rb +9 -0
- data/lib/generators/irwi_wiki_views/irwi_wiki_views_generator.rb +13 -0
- data/lib/irwi_mod.rb +46 -0
- data/lib/irwi_mod/comparators/base.rb +20 -0
- data/lib/irwi_mod/comparators/diff_lcs.rb +54 -0
- data/lib/irwi_mod/comparators/spans/changed_span.rb +18 -0
- data/lib/irwi_mod/comparators/spans/not_changed_span.rb +20 -0
- data/lib/irwi_mod/config.rb +83 -0
- data/lib/irwi_mod/extensions/controllers.rb +18 -0
- data/lib/irwi_mod/extensions/controllers/wiki_page_attachments.rb +21 -0
- data/lib/irwi_mod/extensions/controllers/wiki_pages.rb +167 -0
- data/lib/irwi_mod/extensions/models.rb +24 -0
- data/lib/irwi_mod/extensions/models/wiki_page.rb +55 -0
- data/lib/irwi_mod/extensions/models/wiki_page_attachment.rb +9 -0
- data/lib/irwi_mod/extensions/models/wiki_page_version.rb +44 -0
- data/lib/irwi_mod/formatters/blue_cloth.rb +11 -0
- data/lib/irwi_mod/formatters/red_cloth.rb +11 -0
- data/lib/irwi_mod/formatters/simple_html.rb +10 -0
- data/lib/irwi_mod/formatters/wiki_cloth.rb +11 -0
- data/lib/irwi_mod/helpers.rb +13 -0
- data/lib/irwi_mod/helpers/wiki_page_attachments_helper.rb +25 -0
- data/lib/irwi_mod/helpers/wiki_pages_helper.rb +145 -0
- data/lib/irwi_mod/paginators/none.rb +16 -0
- data/lib/irwi_mod/paginators/will_paginate.rb +11 -0
- data/lib/irwi_mod/support/route_mapper.rb +36 -0
- data/lib/irwi_mod/support/template_finder.rb +11 -0
- data/lib/irwi_mod/version.rb +9 -0
- metadata +231 -0
data/lib/irwi_mod.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'active_support/dependencies'
|
2
|
+
require 'rails_autolink' if defined?(Rails)
|
3
|
+
|
4
|
+
module IrwiMod
|
5
|
+
|
6
|
+
module Formatters
|
7
|
+
autoload :BlueCloth, 'irwi_mod/formatters/blue_cloth'
|
8
|
+
autoload :RedCloth, 'irwi_mod/formatters/red_cloth'
|
9
|
+
autoload :SimpleHtml, 'irwi_mod/formatters/simple_html'
|
10
|
+
autoload :WikiCloth, 'irwi_mod/formatters/wiki_cloth'
|
11
|
+
end
|
12
|
+
|
13
|
+
module Comparators
|
14
|
+
autoload :DiffLcs, 'irwi_mod/comparators/diff_lcs'
|
15
|
+
autoload :Base, 'irwi_mod/comparators/base'
|
16
|
+
module Spans
|
17
|
+
autoload :ChangedSpan, 'irwi_mod/comparators/spans/changed_span'
|
18
|
+
autoload :NotChangedSpan, 'irwi_mod/comparators/spans/not_changed_span'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Extensions; end
|
23
|
+
|
24
|
+
module Paginators
|
25
|
+
autoload :None, 'irwi_mod/paginators/none'
|
26
|
+
autoload :WillPaginate, 'irwi_mod/paginators/will_paginate'
|
27
|
+
end
|
28
|
+
|
29
|
+
module Support
|
30
|
+
autoload :TemplateFinder, 'irwi_mod/support/template_finder'
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.config
|
34
|
+
require 'irwi_mod/config'
|
35
|
+
|
36
|
+
@@config ||= IrwiMod::Config.new
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
require 'irwi_mod/extensions/controllers'
|
42
|
+
require 'irwi_mod/extensions/models'
|
43
|
+
require 'irwi_mod/support/route_mapper' # Routes
|
44
|
+
require 'irwi_mod/helpers'
|
45
|
+
|
46
|
+
ActionController::Base.append_view_path File.expand_path('../../app/views', __FILE__) # Append default views
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'irwi_mod/comparators/spans/changed_span'
|
2
|
+
require 'irwi_mod/comparators/spans/not_changed_span'
|
3
|
+
|
4
|
+
class IrwiMod::Comparators::Base
|
5
|
+
|
6
|
+
def render_changes( old_text, new_text )
|
7
|
+
build_changes( old_text, new_text ).join('').gsub( /\r?\n/, '<br />' )
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def new_not_changed( value )
|
13
|
+
IrwiMod::Comparators::Spans::NotChangedSpan.new( value )
|
14
|
+
end
|
15
|
+
|
16
|
+
def new_changed( action, old_value, new_value )
|
17
|
+
IrwiMod::Comparators::Spans::ChangedSpan.new( action, old_value, new_value )
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'irwi_mod/comparators/base'
|
2
|
+
|
3
|
+
class IrwiMod::Comparators::DiffLcs < IrwiMod::Comparators::Base
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
|
8
|
+
require 'diff/lcs'
|
9
|
+
end
|
10
|
+
|
11
|
+
def build_changes( old_text, new_text )
|
12
|
+
diffs = Diff::LCS.sdiff( (old_text || '').mb_chars, (new_text || '').mb_chars ) # Building symmetric diff sequence
|
13
|
+
changes = [] # Array for our result changes
|
14
|
+
|
15
|
+
diffs.each do |change|
|
16
|
+
case change.action
|
17
|
+
when '=' then
|
18
|
+
if !changes.empty? && changes.last.action == '=' # Append to last not changed span, if exists
|
19
|
+
changes.last.value << change.old_element
|
20
|
+
else
|
21
|
+
changes << new_not_changed( change.old_element )
|
22
|
+
end
|
23
|
+
|
24
|
+
when '+' then
|
25
|
+
if !changes.empty? && changes.last.action == '+' # Append to last addition, if exists
|
26
|
+
changes.last.new_value << change.new_element
|
27
|
+
elsif !changes.empty? && changes.last.action == '!' # Append to last replace, if exists (it's necessary when replacing short string with a new long)
|
28
|
+
changes.last.new_value << change.new_element
|
29
|
+
else
|
30
|
+
changes << new_changed( '+', nil, change.new_element )
|
31
|
+
end
|
32
|
+
|
33
|
+
when '-' then
|
34
|
+
if !changes.empty? && changes.last.action == '-' # Append to last deletion, if exists
|
35
|
+
changes.last.old_value << change.old_element
|
36
|
+
else
|
37
|
+
changes << new_changed( '-', change.old_element, nil )
|
38
|
+
end
|
39
|
+
|
40
|
+
when '!' then
|
41
|
+
if !changes.empty? && changes.last.action == '!' # Append to last replace, if exists
|
42
|
+
changes.last.old_value << change.old_element
|
43
|
+
changes.last.new_value << change.new_element
|
44
|
+
else
|
45
|
+
changes << new_changed( '!', change.old_element, change.new_element )
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
changes
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class IrwiMod::Comparators::Spans::ChangedSpan
|
2
|
+
|
3
|
+
attr_accessor :action, :old_value, :new_value
|
4
|
+
|
5
|
+
def initialize( act, ov, nv )
|
6
|
+
@action = act
|
7
|
+
@old_value = ov
|
8
|
+
@new_value = nv
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
s = ''
|
13
|
+
s << "<span class=\"removed\">#{@old_value}</span>" if @old_value
|
14
|
+
s << "<span class=\"added\">#{@new_value}</span>" if @new_value
|
15
|
+
s
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class IrwiMod::Comparators::Spans::NotChangedSpan
|
2
|
+
|
3
|
+
attr_accessor :value
|
4
|
+
|
5
|
+
def initialize( v )
|
6
|
+
@value = v
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
@value.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def action
|
14
|
+
'='
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method :old_value, :value
|
18
|
+
alias_method :new_value, :value
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class IrwiMod::Config
|
4
|
+
|
5
|
+
attr_accessor :controller_name
|
6
|
+
attr_accessor :user_class_name
|
7
|
+
attr_accessor :page_class_name
|
8
|
+
attr_accessor :page_version_class_name
|
9
|
+
attr_accessor :page_attachment_class_name
|
10
|
+
attr_accessor :page_version_foreign_key
|
11
|
+
|
12
|
+
# Object using to format content
|
13
|
+
attr_writer :formatter
|
14
|
+
|
15
|
+
def formatter
|
16
|
+
@formatter ||= begin
|
17
|
+
require 'irwi_mod/formatters/red_cloth'
|
18
|
+
|
19
|
+
self.formatter = IrwiMod::Formatters::RedCloth.new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Object using to compare pages
|
24
|
+
attr_writer :comparator
|
25
|
+
|
26
|
+
def comparator
|
27
|
+
@comparator ||= begin
|
28
|
+
require 'irwi_mod/comparators/diff_lcs'
|
29
|
+
|
30
|
+
self.comparator = IrwiMod::Comparators::DiffLcs.new
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Object using to paginate collections
|
35
|
+
attr_writer :paginator
|
36
|
+
|
37
|
+
def paginator
|
38
|
+
@paginator ||= begin
|
39
|
+
require 'irwi_mod/paginators/none'
|
40
|
+
|
41
|
+
self.paginator = IrwiMod::Paginators::None.new
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@controller_name = 'wiki_pages'
|
47
|
+
@user_class_name = 'User'
|
48
|
+
@page_class_name = 'WikiPage'
|
49
|
+
@page_version_class_name = 'WikiPageVersion'
|
50
|
+
@page_attachment_class_name = nil
|
51
|
+
@page_version_foreign_key = 'page_id'
|
52
|
+
end
|
53
|
+
|
54
|
+
def page_class
|
55
|
+
page_class_name.constantize
|
56
|
+
end
|
57
|
+
|
58
|
+
def page_version_class
|
59
|
+
page_version_class_name.constantize
|
60
|
+
end
|
61
|
+
|
62
|
+
def page_attachment_class
|
63
|
+
page_attachment_class_name.constantize
|
64
|
+
end
|
65
|
+
|
66
|
+
def user_class
|
67
|
+
user_class_name.constantize
|
68
|
+
end
|
69
|
+
|
70
|
+
def system_pages
|
71
|
+
@system_pages ||= {
|
72
|
+
'all' => 'all'
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Add system page
|
77
|
+
# @param action [String,Symbol] controller action
|
78
|
+
# @param path [String] path in routes
|
79
|
+
def add_system_page( action, path )
|
80
|
+
system_pages[ action.to_s ] = path.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'action_controller'
|
2
|
+
|
3
|
+
module IrwiMod::Extensions::Controllers
|
4
|
+
autoload :WikiPages, 'irwi_mod/extensions/controllers/wiki_pages'
|
5
|
+
autoload :WikiPageAttachments, 'irwi_mod/extensions/controllers/wiki_page_attachments'
|
6
|
+
end
|
7
|
+
|
8
|
+
ActionController::Base.instance_eval do
|
9
|
+
|
10
|
+
# @param config [Hash] config for controller class
|
11
|
+
# @option page_class
|
12
|
+
#
|
13
|
+
def acts_as_wiki_pages_controller( config = {} )
|
14
|
+
include IrwiMod::Extensions::Controllers::WikiPages
|
15
|
+
include IrwiMod::Extensions::Controllers::WikiPageAttachments if IrwiMod::config.page_attachment_class_name
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module IrwiMod::Extensions::Controllers::WikiPageAttachments
|
2
|
+
|
3
|
+
def add_attachment
|
4
|
+
attachment = page_attachment_class.new(params[:wiki_page_attachment])
|
5
|
+
attachment.save!
|
6
|
+
redirect_to url_for(:path => attachment.page.path, :action => :edit)
|
7
|
+
end
|
8
|
+
|
9
|
+
def remove_attachment
|
10
|
+
attachment = page_attachment_class.find(params[:attachment_id])
|
11
|
+
attachment.destroy
|
12
|
+
redirect_to url_for(:path => attachment.page.path, :action => :edit)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def page_attachment_class
|
18
|
+
IrwiMod.config.page_attachment_class
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module IrwiMod::Extensions::Controllers::WikiPages
|
2
|
+
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
def page_class
|
6
|
+
@page_class ||= IrwiMod.config.page_class
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_page_class(arg)
|
10
|
+
@page_class = arg
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
|
17
|
+
include IrwiMod::Extensions::Controllers::WikiPageAttachments
|
18
|
+
include IrwiMod::Support::TemplateFinder
|
19
|
+
|
20
|
+
def index
|
21
|
+
return not_allowed unless show_allowed?
|
22
|
+
|
23
|
+
do_search
|
24
|
+
render_template 'index'
|
25
|
+
end
|
26
|
+
|
27
|
+
def show
|
28
|
+
return not_allowed unless show_allowed?
|
29
|
+
|
30
|
+
render_template( @page.new_record? ? 'no' : 'show' )
|
31
|
+
end
|
32
|
+
|
33
|
+
def history
|
34
|
+
return not_allowed unless history_allowed?
|
35
|
+
|
36
|
+
@versions = IrwiMod.config.paginator.paginate( @page.versions, :page => params[:page] ) # Paginating them
|
37
|
+
|
38
|
+
render_template( @page.new_record? ? 'no' : 'history' )
|
39
|
+
end
|
40
|
+
|
41
|
+
def compare
|
42
|
+
return not_allowed unless history_allowed?
|
43
|
+
|
44
|
+
if @page.new_record?
|
45
|
+
render_template 'no'
|
46
|
+
else
|
47
|
+
new_num = params[:new].to_i || @page.last_version_number # Last version number
|
48
|
+
old_num = params[:old].to_i || 1 # First version number
|
49
|
+
|
50
|
+
old_num, new_num = new_num, old_num if new_num < old_num # Swapping them if last < first
|
51
|
+
|
52
|
+
versions = @page.versions.between( old_num, new_num ) # Loading all versions between first and last
|
53
|
+
|
54
|
+
@versions = IrwiMod.config.paginator.paginate( versions, :page => params[:page] ) # Paginating them
|
55
|
+
|
56
|
+
@new_version = @versions.first.number == new_num ? @versions.first : versions.first # Loading next version
|
57
|
+
@old_version = @versions.last.number == old_num ? @versions.last : versions.last # Loading previous version
|
58
|
+
|
59
|
+
render_template 'compare'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def new
|
64
|
+
return not_allowed unless show_allowed? && edit_allowed?
|
65
|
+
|
66
|
+
render_template 'new'
|
67
|
+
end
|
68
|
+
|
69
|
+
def edit
|
70
|
+
return not_allowed unless show_allowed? && edit_allowed?
|
71
|
+
|
72
|
+
render_template 'edit'
|
73
|
+
end
|
74
|
+
|
75
|
+
def update
|
76
|
+
return not_allowed unless params[:page] && (@page.new_record? || edit_allowed?) # Check for rights (but not for new record, for it we will use second check only)
|
77
|
+
|
78
|
+
@page.attributes = params[:page] # Assign new attributes
|
79
|
+
@page.comment = params[:page][:comment]
|
80
|
+
|
81
|
+
return not_allowed unless edit_allowed? # Double check: used beacause action may become invalid after attributes update
|
82
|
+
|
83
|
+
@page.updator = @main_current_user # Assing user, which updated page
|
84
|
+
@page.creator = @main_current_user if @page.new_record? # Assign it's creator if it's new page
|
85
|
+
|
86
|
+
if !params[:preview] && (params[:cancel] || @page.save)
|
87
|
+
redirect_to url_for( :action => :show, :path => @page.path.split('/') ) # redirect to new page's path (if it changed)
|
88
|
+
else
|
89
|
+
render_template 'edit'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def destroy
|
94
|
+
return not_allowed unless destroy_allowed?
|
95
|
+
|
96
|
+
@page.destroy
|
97
|
+
|
98
|
+
redirect_to url_for( :action => :show )
|
99
|
+
end
|
100
|
+
|
101
|
+
def all
|
102
|
+
do_search
|
103
|
+
render_template 'all'
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
def do_search
|
108
|
+
@pages = IrwiMod.config.paginator.paginate( page_class, :page => params[:page] ) # Loading and paginating all pages
|
109
|
+
end
|
110
|
+
# Retrieves wiki_page_class for this controller
|
111
|
+
def page_class
|
112
|
+
self.class.page_class
|
113
|
+
end
|
114
|
+
|
115
|
+
# Renders user-specified or default template
|
116
|
+
def render_template( template )
|
117
|
+
render "#{template_dir template}/#{template}", :status => (case template when 'no' then 404 when 'not_allowed' then 403 else 200 end)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Initialize @main_current_user instance variable
|
121
|
+
def setup_main_current_user
|
122
|
+
@main_current_user = respond_to?( :main_current_user, true ) ? main_current_user : nil # Find user by main_current_user method or return nil
|
123
|
+
end
|
124
|
+
|
125
|
+
# Initialize @page instance variable
|
126
|
+
def setup_page
|
127
|
+
@page = page_class.find_by_path_or_new( params[:path] || '' ) # Find existing page by path or create new
|
128
|
+
end
|
129
|
+
|
130
|
+
# Method, which called when user tries to visit
|
131
|
+
def not_allowed
|
132
|
+
render_template 'not_allowed'
|
133
|
+
end
|
134
|
+
|
135
|
+
# Check is it allowed for current user to see current page. Designed to be redefined by application programmer
|
136
|
+
def show_allowed?
|
137
|
+
true
|
138
|
+
end
|
139
|
+
|
140
|
+
# Check is it allowed for current user see current page history. Designed to be redefined by application programmer
|
141
|
+
def history_allowed?
|
142
|
+
show_allowed?
|
143
|
+
end
|
144
|
+
|
145
|
+
# Check is it allowed for current user edit current page. Designed to be redefined by application programmer
|
146
|
+
def edit_allowed?
|
147
|
+
show_allowed?
|
148
|
+
end
|
149
|
+
|
150
|
+
# Check is it allowed for current user destroy current page. Designed to be redefined by application programmer
|
151
|
+
def destroy_allowed?
|
152
|
+
edit_allowed?
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.included( base )
|
158
|
+
base.send :extend, IrwiMod::Extensions::Controllers::WikiPages::ClassMethods
|
159
|
+
base.send :include, IrwiMod::Extensions::Controllers::WikiPages::InstanceMethods
|
160
|
+
|
161
|
+
base.before_filter :setup_main_current_user # Setup @setup_main_current_user instance variable before each action
|
162
|
+
# Setup @page instance variable before each action
|
163
|
+
base.before_filter :setup_page, :only => [ :show, :history, :compare, :new, :edit, :update, :destroy, :add_attachment ]
|
164
|
+
base.helper_method :show_allowed?, :edit_allowed?, :history_allowed?, :destroy_allowed? # Access control methods are avaliable in views
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|