##// END OF EJS Templates
remove trailing white-spaces from app/models/wiki_page.rb....
Toshi MARUYAMA -
r6391:ff8af0ea2e4a
parent child
Show More
@@ -1,221 +1,221
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 #
8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 #
13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'diff'
19 19 require 'enumerator'
20 20
21 21 class WikiPage < ActiveRecord::Base
22 22 belongs_to :wiki
23 23 has_one :content, :class_name => 'WikiContent', :foreign_key => 'page_id', :dependent => :destroy
24 24 acts_as_attachable :delete_permission => :delete_wiki_pages_attachments
25 25 acts_as_tree :dependent => :nullify, :order => 'title'
26 26
27 27 acts_as_watchable
28 28 acts_as_event :title => Proc.new {|o| "#{l(:label_wiki)}: #{o.title}"},
29 29 :description => :text,
30 30 :datetime => :created_on,
31 31 :url => Proc.new {|o| {:controller => 'wiki', :action => 'show', :project_id => o.wiki.project, :id => o.title}}
32 32
33 33 acts_as_searchable :columns => ['title', 'text'],
34 34 :include => [{:wiki => :project}, :content],
35 35 :permission => :view_wiki_pages,
36 36 :project_key => "#{Wiki.table_name}.project_id"
37 37
38 38 attr_accessor :redirect_existing_links
39
39
40 40 validates_presence_of :title
41 41 validates_format_of :title, :with => /^[^,\.\/\?\;\|\s]*$/
42 42 validates_uniqueness_of :title, :scope => :wiki_id, :case_sensitive => false
43 43 validates_associated :content
44
44
45 45 # eager load information about last updates, without loading text
46 46 named_scope :with_updated_on, {
47 47 :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
48 48 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id"
49 49 }
50
50
51 51 # Wiki pages that are protected by default
52 52 DEFAULT_PROTECTED_PAGES = %w(sidebar)
53
53
54 54 def after_initialize
55 55 if new_record? && DEFAULT_PROTECTED_PAGES.include?(title.to_s.downcase)
56 56 self.protected = true
57 57 end
58 58 end
59
59
60 60 def visible?(user=User.current)
61 61 !user.nil? && user.allowed_to?(:view_wiki_pages, project)
62 62 end
63 63
64 64 def title=(value)
65 65 value = Wiki.titleize(value)
66 66 @previous_title = read_attribute(:title) if @previous_title.blank?
67 67 write_attribute(:title, value)
68 68 end
69 69
70 70 def before_save
71 self.title = Wiki.titleize(title)
71 self.title = Wiki.titleize(title)
72 72 # Manage redirects if the title has changed
73 73 if !@previous_title.blank? && (@previous_title != title) && !new_record?
74 74 # Update redirects that point to the old title
75 75 wiki.redirects.find_all_by_redirects_to(@previous_title).each do |r|
76 76 r.redirects_to = title
77 77 r.title == r.redirects_to ? r.destroy : r.save
78 78 end
79 79 # Remove redirects for the new title
80 80 wiki.redirects.find_all_by_title(title).each(&:destroy)
81 81 # Create a redirect to the new title
82 82 wiki.redirects << WikiRedirect.new(:title => @previous_title, :redirects_to => title) unless redirect_existing_links == "0"
83 83 @previous_title = nil
84 84 end
85 85 end
86
86
87 87 def before_destroy
88 88 # Remove redirects to this page
89 89 wiki.redirects.find_all_by_redirects_to(title).each(&:destroy)
90 90 end
91
91
92 92 def pretty_title
93 93 WikiPage.pretty_title(title)
94 94 end
95
95
96 96 def content_for_version(version=nil)
97 97 result = content.versions.find_by_version(version.to_i) if version
98 98 result ||= content
99 99 result
100 100 end
101
101
102 102 def diff(version_to=nil, version_from=nil)
103 103 version_to = version_to ? version_to.to_i : self.content.version
104 104 version_from = version_from ? version_from.to_i : version_to - 1
105 105 version_to, version_from = version_from, version_to unless version_from < version_to
106
106
107 107 content_to = content.versions.find_by_version(version_to)
108 108 content_from = content.versions.find_by_version(version_from)
109
109
110 110 (content_to && content_from) ? WikiDiff.new(content_to, content_from) : nil
111 111 end
112
112
113 113 def annotate(version=nil)
114 114 version = version ? version.to_i : self.content.version
115 115 c = content.versions.find_by_version(version)
116 116 c ? WikiAnnotate.new(c) : nil
117 117 end
118
118
119 119 def self.pretty_title(str)
120 120 (str && str.is_a?(String)) ? str.tr('_', ' ') : str
121 121 end
122
122
123 123 def project
124 124 wiki.project
125 125 end
126
126
127 127 def text
128 128 content.text if content
129 129 end
130
130
131 131 def updated_on
132 132 unless @updated_on
133 133 if time = read_attribute(:updated_on)
134 134 # content updated_on was eager loaded with the page
135 135 @updated_on = Time.parse(time) rescue nil
136 136 else
137 137 @updated_on = content && content.updated_on
138 138 end
139 139 end
140 140 @updated_on
141 141 end
142
142
143 143 # Returns true if usr is allowed to edit the page, otherwise false
144 144 def editable_by?(usr)
145 145 !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project)
146 146 end
147
147
148 148 def attachments_deletable?(usr=User.current)
149 149 editable_by?(usr) && super(usr)
150 150 end
151
151
152 152 def parent_title
153 153 @parent_title || (self.parent && self.parent.pretty_title)
154 154 end
155
155
156 156 def parent_title=(t)
157 157 @parent_title = t
158 158 parent_page = t.blank? ? nil : self.wiki.find_page(t)
159 159 self.parent = parent_page
160 160 end
161 161
162 162 protected
163
163
164 164 def validate
165 165 errors.add(:parent_title, :invalid) if !@parent_title.blank? && parent.nil?
166 166 errors.add(:parent_title, :circular_dependency) if parent && (parent == self || parent.ancestors.include?(self))
167 167 errors.add(:parent_title, :not_same_project) if parent && (parent.wiki_id != wiki_id)
168 168 end
169 169 end
170 170
171 171 class WikiDiff < Redmine::Helpers::Diff
172 172 attr_reader :content_to, :content_from
173
173
174 174 def initialize(content_to, content_from)
175 175 @content_to = content_to
176 176 @content_from = content_from
177 177 super(content_to.text, content_from.text)
178 178 end
179 179 end
180 180
181 181 class WikiAnnotate
182 182 attr_reader :lines, :content
183
183
184 184 def initialize(content)
185 185 @content = content
186 186 current = content
187 187 current_lines = current.text.split(/\r?\n/)
188 188 @lines = current_lines.collect {|t| [nil, nil, t]}
189 189 positions = []
190 190 current_lines.size.times {|i| positions << i}
191 191 while (current.previous)
192 192 d = current.previous.text.split(/\r?\n/).diff(current.text.split(/\r?\n/)).diffs.flatten
193 193 d.each_slice(3) do |s|
194 194 sign, line = s[0], s[1]
195 195 if sign == '+' && positions[line] && positions[line] != -1
196 196 if @lines[positions[line]][0].nil?
197 197 @lines[positions[line]][0] = current.version
198 198 @lines[positions[line]][1] = current.author
199 199 end
200 200 end
201 201 end
202 202 d.each_slice(3) do |s|
203 203 sign, line = s[0], s[1]
204 204 if sign == '-'
205 205 positions.insert(line, -1)
206 206 else
207 207 positions[line] = nil
208 208 end
209 209 end
210 210 positions.compact!
211 211 # Stop if every line is annotated
212 212 break unless @lines.detect { |line| line[0].nil? }
213 213 current = current.previous
214 214 end
215 @lines.each { |line|
215 @lines.each { |line|
216 216 line[0] ||= current.version
217 217 # if the last known version is > 1 (eg. history was cleared), we don't know the author
218 218 line[1] ||= current.author if current.version == 1
219 219 }
220 220 end
221 221 end
General Comments 0
You need to be logged in to leave comments. Login now