Soks 0.0.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +2 -0
- data/README.txt +3 -2
- data/TODO.txt +31 -0
- data/bin/soks-create-wiki.rb +0 -1
- data/lib/authenticators.rb +30 -4
- data/lib/helpers/counter-helpers.rb +132 -0
- data/lib/helpers/default-helpers.rb +170 -169
- data/lib/helpers/mail2wiki-helper.rb +18 -22
- data/lib/helpers/maintenance-helpers.rb +149 -0
- data/lib/helpers/rss2wiki-helper.rb +7 -8
- data/lib/soks-model.rb +82 -54
- data/lib/soks-servlet.rb +126 -108
- data/lib/soks-storage.rb +74 -11
- data/lib/soks-utils.rb +77 -3
- data/lib/soks-view.rb +169 -103
- data/lib/soks.rb +5 -23
- data/templates/default/attachment/newpage.js +4 -13
- data/templates/default/attachment/print_stylesheet.css +2 -7
- data/templates/default/caches/readme.txt +1 -0
- data/templates/default/content/Api%20for%20classes%20to%20modify%20the%20wiki.textile +2 -0
- data/templates/default/content/Author.textile +4 -1
- data/templates/default/content/Automatic%20Summaries.textile +16 -53
- data/templates/default/content/Automatic%20linking%20between%20pages.textile +3 -3
- data/templates/default/content/{bug%3A%20competing%20edits.textile → Bug%3A%20Competing%20edits.textile} +9 -0
- data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +2 -0
- data/templates/default/content/Bug%3A%20E%2Dmail%20addresses%20with%20hyphens%20not%20recognised.textile +17 -0
- data/templates/default/content/Bug%3A%20Email%20adresses%20in%20page%20titles%20cause%20incorrec.textile +3 -0
- data/templates/default/content/Bug%3A%20GEM%20limits%20title%20lengths.textile +3 -1
- data/templates/default/content/Bug%3A%20Memory%20leak.textile +13 -0
- data/templates/default/content/Bug%3A%20Pages%20that%20link%20here%20may%20not%20appear%20on%20r.textile +13 -0
- data/templates/default/content/Bug%3A%20Textile%20mishandles%20paragraphs.textile +4 -0
- data/templates/default/content/Bug%3A%20Unanticipated%20Rollbacks.textile +2 -0
- data/templates/default/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +2 -0
- data/templates/default/content/Home%20Page.textile +3 -1
- data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +23 -13
- data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +3 -1
- data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +22 -0
- data/templates/default/content/How%20to%20get%20the%20latest%20Soks%20from%20cvs.textile +2 -0
- data/templates/default/content/How%20to%20hack%20soks.textile +2 -0
- data/templates/default/content/How%20to%20import%20a%20site%20from%20instiki.textile +2 -0
- data/templates/default/content/{How%20to%20import%20data%20to%20this%20wiki.textile → How%20to%20import%20data.textile} +3 -7
- data/templates/default/content/How%20to%20install%20Soks.textile +2 -0
- data/templates/default/content/How%20to%20password%20protect%20your%20wiki.textile +21 -11
- data/templates/default/content/How%20to%20report%20a%20bug.textile +2 -1
- data/templates/default/content/How%20to%20upgrade%20soks.textile +22 -0
- data/templates/default/content/How%20to%20use%20the%20keyboard%20shortcuts.textile +2 -2
- data/templates/default/content/How%20to%20use%20this%20wiki.textile +3 -1
- data/templates/default/content/List%20of%20changes.textile +84 -118
- data/templates/default/content/News%3A%20Version%201%2D0%2D0%20released.textile +19 -0
- data/templates/default/content/Pages%20to%20include%20in%20the%20distribution.textile +51 -0
- data/templates/default/content/Per%20Wiki%20Templates.textile +2 -0
- data/templates/default/content/Planned%20Features.textile +30 -9
- data/templates/default/content/README.textile +3 -2
- data/templates/default/content/RSS%20feed.textile +1 -1
- data/templates/default/content/Recent%20changes%20to%20this%20site.textile +283 -0
- data/templates/default/content/SOKS%20features.textile +3 -0
- data/templates/default/content/Site%20Index.textile +202 -0
- data/templates/default/content/Soks%20Licence.textile +2 -0
- data/templates/default/content/Tag%3A%20Include%20this%20page%20in%20the%20distribution.textile +6 -0
- data/templates/default/start.rb +67 -123
- data/templates/default/version.txt +1 -1
- data/templates/default/views/Page_edit.rhtml +7 -7
- data/templates/default/views/{Page_search_results.rhtml → Page_find.rhtml} +9 -3
- data/templates/default/views/Page_linksfromrss.rhtml +24 -0
- data/templates/default/views/Page_listrss.rhtml +46 -0
- data/templates/default/views/Page_meta.rhtml +1 -1
- data/templates/default/views/Page_revision.rhtml +39 -0
- data/templates/default/views/Page_revisions.rhtml +13 -5
- data/templates/default/views/Page_rss.rhtml +8 -8
- data/templates/default/views/Page_view.rhtml +3 -3
- data/templates/default/views/UploadPage_edit.rhtml +8 -8
- data/templates/default/views/frame.rhtml +8 -8
- data/templates/default/views/messages.yaml +1 -0
- data/test/html/2006Mar.html +66 -0
- data/test/html/poignant.html +36 -0
- data/test/html/poignant.textile +36 -0
- data/test/mock-objects.rb +69 -0
- data/test/stress_url_calls.rb +33 -0
- data/test/stress_urls.txt +68 -0
- data/test/test_counter-helper.rb +158 -0
- data/test/test_soks-helper-maintenance.rb +106 -0
- data/test/test_soks-helpers.rb +104 -0
- data/test/test_soks-model.rb +144 -0
- data/test/test_soks-servlet.rb +231 -0
- data/test/test_soks-storage.rb +70 -31
- data/test/test_soks-utils.rb +112 -13
- data/test/test_soks-view.rb +141 -3
- metadata +38 -27
- data/templates/default/content/A%20page%20with%20an%20umlaut%20%F6%20in%20its%20title.textile +0 -1
- data/templates/default/content/All%20News.textile +0 -26
- data/templates/default/content/Bil%20Kleb.textile +0 -1
- data/templates/default/content/Bil.textile +0 -1
- data/templates/default/content/Bill%20Wood.textile +0 -3
- data/templates/default/content/Bug%3A%20RSS%20feed%20does%20not%20validate.textile +0 -10
- data/templates/default/content/Bug%3A%20Type%20a%20title%20here.textile +0 -31
- data/templates/default/content/Instructions%20and%20Howtos.textile +0 -21
- data/templates/default/content/Latest%20News.textile +0 -26
- data/templates/default/content/New%20Recent%20Changes%20class.textile +0 -68
- data/templates/default/content/New%20page%20templates%20or%20categories%20code.textile +0 -68
- data/templates/default/content/News%3A%20Version%200%2E0%2E6%20Released.textile +0 -13
- data/templates/default/content/Recent%20Blog%20Entries.textile +0 -5
- data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +0 -286
- data/templates/default/content/Ruby.textile +0 -9
- data/templates/default/content/Skorgu.textile +0 -3
- data/templates/default/content/ctrl%2Dn.textile +0 -1
- data/templates/default/content/let%20me%20know.textile +0 -1
- data/templates/default/content/sandbox.textile +0 -20
- data/templates/default/content/tamc.textile +0 -1
- data/templates/default/content/tamc2.textile +0 -1
data/lib/soks-view.rb
CHANGED
|
@@ -1,17 +1,54 @@
|
|
|
1
|
+
# Extend the model classes to provide view functions
|
|
2
|
+
class Page
|
|
3
|
+
def textile( view = nil )
|
|
4
|
+
return "[[#{$MESSAGES[:Create]} #{name} => /edit/#{name} ]]" if empty?
|
|
5
|
+
content
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class ImagePage
|
|
10
|
+
def textile( view )
|
|
11
|
+
return "[[#{$MESSAGES[:Create]} #{name} => /edit/#{name} ]]" if empty?
|
|
12
|
+
return content if deleted?
|
|
13
|
+
"!#{view.file2(content)}!:#{view.url(name)}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class AttachmentPage
|
|
18
|
+
def textile( view )
|
|
19
|
+
return "[[#{$MESSAGES[:Create]} #{name} => /edit/#{name} ]]" if empty?
|
|
20
|
+
return content if deleted?
|
|
21
|
+
%Q{[[ #{name} => #{view.file2(content)} ]]\n}
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
1
25
|
# This module is used to extend each erb page to provide helper methods
|
|
2
26
|
module ErbHelper
|
|
3
27
|
|
|
4
|
-
|
|
5
|
-
|
|
28
|
+
attr_accessor :name
|
|
29
|
+
attr_accessor :description
|
|
30
|
+
attr_accessor :author_to_email_conversion
|
|
31
|
+
|
|
32
|
+
def url( name, view = 'view', query = '' )
|
|
33
|
+
"#{root_url}/#{view}/#{url_name_for_page_name(name)}#{query}"
|
|
6
34
|
end
|
|
7
35
|
|
|
8
36
|
def file( name )
|
|
9
|
-
"#{
|
|
37
|
+
"#{root_url}/attachment/#{name}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Will refactor this out eventually and merge with above
|
|
41
|
+
def file2( name )
|
|
42
|
+
name = name[1..-1] if name[0,1] == '/'
|
|
43
|
+
"#{root_url}/#{name.strip}"
|
|
10
44
|
end
|
|
11
45
|
end
|
|
12
46
|
|
|
13
47
|
# This class records all the links between pages
|
|
14
48
|
class Links
|
|
49
|
+
|
|
50
|
+
attr_reader :links
|
|
51
|
+
|
|
15
52
|
def initialize
|
|
16
53
|
@links = Hash.new
|
|
17
54
|
end
|
|
@@ -48,7 +85,7 @@ end
|
|
|
48
85
|
class BruteMatch
|
|
49
86
|
|
|
50
87
|
IGNORE_CASE = true
|
|
51
|
-
|
|
88
|
+
|
|
52
89
|
def initialize
|
|
53
90
|
@matches = Hash.new
|
|
54
91
|
@titles = Array.new #sorted array for speed
|
|
@@ -70,18 +107,19 @@ class BruteMatch
|
|
|
70
107
|
end
|
|
71
108
|
|
|
72
109
|
def match( text )
|
|
73
|
-
@titles.each do |title|
|
|
74
|
-
regexp
|
|
75
|
-
page = @matches[ title ]
|
|
76
|
-
text.gsub!( regexp ) { |match| yield match, page }
|
|
110
|
+
@titles.each do |title,regexp,page|
|
|
111
|
+
text.gsub!( regexp ) { |match| "#{$1}#{yield $2, page}#{$3}" }
|
|
77
112
|
end
|
|
78
113
|
text
|
|
79
114
|
end
|
|
80
115
|
|
|
81
116
|
private
|
|
82
117
|
|
|
118
|
+
# The title, a regexp to match for the title, and the page are stored in a sorted array
|
|
83
119
|
def update_titles
|
|
84
|
-
@titles = @matches.keys.sort_by { |title| title.length }.reverse
|
|
120
|
+
@titles = @matches.keys.sort_by { |title| title.length }.reverse.map do |title|
|
|
121
|
+
[ title, /(^|\W)(#{Regexp.escape( title )})(\W|$)/i, @matches[ title ] ]
|
|
122
|
+
end
|
|
85
123
|
end
|
|
86
124
|
|
|
87
125
|
def lower_case( text )
|
|
@@ -98,17 +136,17 @@ end
|
|
|
98
136
|
# * Automatically links things that look like email addresses and urls
|
|
99
137
|
class WikiRedCloth < RedCloth
|
|
100
138
|
|
|
101
|
-
RULES = [:refs_soks_bracketed_link, :
|
|
139
|
+
RULES = [:refs_soks_bracketed_link, :refs_textile, :block_textile_table, :block_textile_lists,:block_textile_prefix, :inline_textile_image, :inline_textile_link, :inline_textile_code, :inline_soks, :inline_textile_glyphs, :inline_textile_span, :refs_markdown, :block_markdown_setext, :block_markdown_atx, :block_markdown_rule, :block_markdown_bq, :block_markdown_lists, :inline_markdown_reflink, :inline_markdown_link ]
|
|
102
140
|
|
|
103
|
-
def initialize( wiki, page, string )
|
|
104
|
-
@wiki, @page = wiki, page
|
|
141
|
+
def initialize( wiki, page, string, hard_breaks = false )
|
|
142
|
+
@wiki, @view, @page = wiki, wiki, page
|
|
105
143
|
@internal_links_from_page = []
|
|
106
|
-
super(insert_sub_strings( string.dup ),
|
|
107
|
-
self.hard_breaks =
|
|
144
|
+
super(insert_sub_strings( string.dup ),[:no_span_caps])
|
|
145
|
+
self.hard_breaks = hard_breaks
|
|
108
146
|
end
|
|
109
147
|
|
|
110
148
|
def to_html
|
|
111
|
-
super( *RULES )
|
|
149
|
+
super( *RULES ).to_s
|
|
112
150
|
end
|
|
113
151
|
|
|
114
152
|
def inline_soks( text )
|
|
@@ -149,16 +187,14 @@ class WikiRedCloth < RedCloth
|
|
|
149
187
|
|
|
150
188
|
def insert_sub_strings( text, count = 0 )
|
|
151
189
|
return text if count > 5 # Stops us getting locked into a cycle if people mess up the insert
|
|
152
|
-
text.gsub!(/\[\[\s*(insert (.+?))\s*\]\]/i) do |
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if @wiki.exists? inserted_page.name
|
|
156
|
-
@internal_links_from_page << inserted_page
|
|
157
|
-
inserted_page.is_inserted_into( @page )
|
|
158
|
-
end
|
|
159
|
-
insert_sub_strings( "#{inserted_page.textile}\n", count + 1 )
|
|
190
|
+
text.gsub!(/\[\[\s*(insert (.+?))\s*\]\]/i) do |match|
|
|
191
|
+
if @wiki.exists? $1 # So we don't accidentlaly match a page whose name starts 'insert'
|
|
192
|
+
match
|
|
160
193
|
else
|
|
161
|
-
|
|
194
|
+
inserted_page = @wiki.page( $2 )
|
|
195
|
+
@internal_links_from_page << inserted_page if @wiki.exists? inserted_page.name
|
|
196
|
+
inserted_page.is_inserted_into( @page )
|
|
197
|
+
insert_sub_strings( "#{inserted_page.textile(@view)}\n", count + 1 )
|
|
162
198
|
end
|
|
163
199
|
end
|
|
164
200
|
text
|
|
@@ -176,107 +212,140 @@ class WikiRedCloth < RedCloth
|
|
|
176
212
|
title, pagename = $1, $3
|
|
177
213
|
pagename ||= title
|
|
178
214
|
case pagename
|
|
215
|
+
|
|
216
|
+
# http://soks.rubyforge.org/index
|
|
217
|
+
when /^http(s)?:\/\//i ; link(pagename,title)
|
|
218
|
+
|
|
219
|
+
# www.soks.org
|
|
179
220
|
when /^www\./i ; link("http://#{pagename}", title )
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
221
|
+
|
|
222
|
+
# tamc@soks.org
|
|
223
|
+
when /[A-Za-z0-9.]+?@[A-Za-z0-9.]+/ ; link("mailto:#{pagename}",title)
|
|
224
|
+
|
|
225
|
+
# /revision/Home page?revision=10
|
|
226
|
+
when %r{^/(\w+)/(.+?)(\?\w+=\w+)$}
|
|
227
|
+
@internal_links_from_page << @wiki.page($2) if @wiki.exists?($2)
|
|
228
|
+
link( @view.url($2,$1,$3), title, @wiki.exists?($2) ? '':'missing' )
|
|
229
|
+
|
|
230
|
+
# /edit/a new page
|
|
231
|
+
when %r{^/(\w+)/(.+)}
|
|
232
|
+
@internal_links_from_page << @wiki.page($2) if @wiki.exists?($2)
|
|
233
|
+
link( @view.url($2,$1), title, @wiki.exists?($2) ? '':'missing' )
|
|
234
|
+
|
|
235
|
+
# the name of a page
|
|
236
|
+
else
|
|
237
|
+
@internal_links_from_page << @wiki.page(pagename) if @wiki.exists? pagename
|
|
238
|
+
link( @view.url( pagename ), title, @wiki.exists?(pagename) ? '':'missing' )
|
|
183
239
|
end
|
|
184
240
|
end
|
|
185
241
|
end
|
|
186
242
|
|
|
187
|
-
def inline_soks_automatic_link( text )
|
|
188
|
-
@wiki.rollingmatch.match( text )
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
def wiki_link( pagename, title, css_class = nil )
|
|
192
|
-
if @wiki.exists? pagename
|
|
193
|
-
@internal_links_from_page << @wiki.page( pagename )
|
|
194
|
-
css_class ||= ''
|
|
243
|
+
def inline_soks_automatic_link( text )
|
|
244
|
+
@wiki.rollingmatch.match( text ) do |title, page|
|
|
245
|
+
@internal_links_from_page << page
|
|
246
|
+
link( @view.url(page.name), title, 'automatic' )
|
|
195
247
|
end
|
|
196
|
-
link( url_for(pagename), title, css_class || 'missing')
|
|
197
248
|
end
|
|
198
249
|
|
|
199
250
|
def link( url, title = url, css_class = '' )
|
|
200
251
|
shelve "<a href='#{url}' class='#{css_class}'>#{title}</a>"
|
|
201
252
|
end
|
|
202
253
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
module PageNameToUrlNameConversion
|
|
257
|
+
|
|
258
|
+
def setup_page_name_to_url_name_conversion
|
|
259
|
+
@urls_to_pages, @pages_to_urls = {}, {}
|
|
260
|
+
@wiki.each { |name,page| url_name_for_page_name( page.name ) }
|
|
261
|
+
@wiki.watch_attentively_for(:page_created) {|event,page,revision| url_name_for_page_name( page.name )}
|
|
262
|
+
@wiki.watch_attentively_for(:page_title_recapitalized) {|event,page| change_caps_for( page.name )}
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# To allow punctuation in page titles and not mess up urls
|
|
266
|
+
def url_name_for_page_name( page_name )
|
|
267
|
+
@pages_to_urls[ page_name.downcase ] || add_url_name_for_page_name( page_name )
|
|
206
268
|
end
|
|
207
269
|
|
|
270
|
+
def page_name_for_url_name( url_name )
|
|
271
|
+
@urls_to_pages[ url_name.downcase ] || url_name
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def add_url_name_for_page_name( page_name )
|
|
275
|
+
url_name = create_url_name( page_name )
|
|
276
|
+
@pages_to_urls[ page_name.downcase ] = url_name
|
|
277
|
+
@urls_to_pages[ url_name.downcase ] = page_name
|
|
278
|
+
url_name
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def change_caps_for( page_name )
|
|
282
|
+
url_name = @pages_to_urls[ page_name.downcase ].downcase
|
|
283
|
+
@urls_to_pages[ url_name ] = page_name
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Turns text into a WikiWord by changing the capitalization and then dumping the punctuation
|
|
287
|
+
def create_url_name( page_name )
|
|
288
|
+
url_name = page_name.capitalize.gsub(/(\W+(\w))/) { |m| $1.upcase }.gsub(/\W+/,'')
|
|
289
|
+
url_name = "PunctuationOnlyInTitle" if url_name == ""
|
|
290
|
+
url_name = increment_url_name( url_name ) while @urls_to_pages.has_key? url_name.downcase
|
|
291
|
+
url_name
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def increment_url_name( url_name )
|
|
295
|
+
if url_name =~ /(\w+)-(\d+)/
|
|
296
|
+
"#{$1}-#{$2.to_i.succ}"
|
|
297
|
+
else
|
|
298
|
+
url_name+"-2"
|
|
299
|
+
end
|
|
300
|
+
end
|
|
208
301
|
end
|
|
209
302
|
|
|
210
303
|
class View
|
|
211
|
-
|
|
212
304
|
include ErbHelper
|
|
305
|
+
include PageNameToUrlNameConversion
|
|
213
306
|
|
|
214
|
-
|
|
307
|
+
REDCLOTH_CACHE_NAME = 'redcloth'
|
|
215
308
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
309
|
+
attr_reader :rollingmatch, :links
|
|
310
|
+
attr_accessor :view_folder
|
|
311
|
+
attr_accessor :root_url
|
|
312
|
+
attr_accessor :reload_erb_each_request
|
|
313
|
+
attr_accessor :dont_frame_views
|
|
314
|
+
attr_accessor :redcloth_hard_breaks
|
|
315
|
+
|
|
316
|
+
def initialize( wiki, root_url, view_folder )
|
|
317
|
+
@wiki, @root_url, @view_folder = wiki, root_url, view_folder
|
|
318
|
+
@rollingmatch, @links = BruteMatch.new, Links.new
|
|
319
|
+
@redcloth_cache = wiki.load_cache(REDCLOTH_CACHE_NAME) || Hash.new
|
|
320
|
+
@erb_cache = Hash.new
|
|
321
|
+
@reload_erb_each_request = false
|
|
322
|
+
@dont_frame_views = []
|
|
323
|
+
@redcloth_hard_breaks = false
|
|
324
|
+
setup_page_name_to_url_name_conversion
|
|
220
325
|
wiki.watch_attentively_for( :page_revised ) { |event,page,revision| refresh_redcloth( page ) }
|
|
326
|
+
wiki.watch_for(:shutdown) { wiki.save_cache(REDCLOTH_CACHE_NAME,@redcloth_cache) }
|
|
221
327
|
end
|
|
222
328
|
|
|
223
|
-
def
|
|
224
|
-
page = @wiki.page pagename
|
|
329
|
+
def render( pagename, view = 'view', person = 'Anon.', query = {} )
|
|
330
|
+
page = @wiki.page( pagename )
|
|
225
331
|
renderedview = redcloth( page )
|
|
226
332
|
content_of_page = html( page.class, view, binding )
|
|
333
|
+
@wiki.notify(:page_viewed, page, view, person)
|
|
227
334
|
if should_frame? view
|
|
228
|
-
frame_erb.result
|
|
335
|
+
return frame_erb.result(binding)
|
|
229
336
|
else
|
|
230
|
-
content_of_page
|
|
337
|
+
return content_of_page
|
|
231
338
|
end
|
|
232
339
|
end
|
|
233
|
-
|
|
234
|
-
def find( pagename )
|
|
235
|
-
return view( pagename ) if @wiki.exists?( pagename )
|
|
236
|
-
view = 'find'
|
|
237
|
-
search_term = /#{pagename}/i
|
|
238
|
-
title_results = @wiki.select { |name,page| name=~ search_term }
|
|
239
|
-
text_results = @wiki.select { |name,page| page.content=~ search_term }
|
|
240
|
-
content_of_page = html( Page, 'search_results', binding )
|
|
241
|
-
page = nil
|
|
242
|
-
frame_erb.result binding
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
def revise( pagename, content, person, newpagename = pagename )
|
|
246
|
-
if @wiki.exists?( pagename ) && (newpagename != pagename)
|
|
247
|
-
@wiki.revise( pagename, "#{$MESSAGES[:content_moved_to]} [[#{newpagename}]]", person )
|
|
248
|
-
@wiki.revise( newpagename, "#{$MESSAGES[:content_moved_from]} [[#{pagename}]]", 'AutomaticPageMover' )
|
|
249
|
-
@wiki.revise( newpagename, content, person )
|
|
250
|
-
else
|
|
251
|
-
@wiki.revise( newpagename, content, person )
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
def move( oldpagename, person, newpagename )
|
|
256
|
-
unless newpagename == oldpagename
|
|
257
|
-
@wiki.revise( newpagename, "#{$MESSAGES[:content_moved_from]} [[#{oldpagename}]]", 'AutomaticPageMover')
|
|
258
|
-
@wiki.revise( newpagename, @wiki.page( oldpagename ).content, person)
|
|
259
|
-
@wiki.revise( oldpagename, "#{$MESSAGES[:content_moved_to]} [[#{newpagename}]]", person)
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def rollback( pagename, revision, person )
|
|
264
|
-
@wiki.rollback( pagename, revision, person )
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def delete( pagename, person )
|
|
268
|
-
@wiki.revise( pagename, $MESSAGES[:page_deleted], person )
|
|
269
|
-
end
|
|
270
340
|
|
|
271
341
|
def refresh_redcloth( page )
|
|
272
342
|
$LOG.info "Refreshing #{page}"
|
|
273
|
-
@redcloth_cache[page] =
|
|
274
|
-
@redcloth_cache[ page ] = WikiRedCloth.new( self, page, page.textile ).to_html
|
|
343
|
+
@redcloth_cache[ page.name ] = WikiRedCloth.new( self, page, page.textile(self), redcloth_hard_breaks).to_html
|
|
275
344
|
end
|
|
276
345
|
|
|
277
346
|
def redcloth( page )
|
|
278
|
-
|
|
279
|
-
@redcloth_cache[ page ]
|
|
347
|
+
textile = page.textile(self)
|
|
348
|
+
@redcloth_cache[ page.name ] || refresh_redcloth( page )
|
|
280
349
|
end
|
|
281
350
|
|
|
282
351
|
def clear_redcloth_cache( page = :all_pages )
|
|
@@ -284,7 +353,7 @@ class View
|
|
|
284
353
|
end
|
|
285
354
|
|
|
286
355
|
def html( klass, view, _binding )
|
|
287
|
-
@erb_cache.clear if
|
|
356
|
+
@erb_cache.clear if reload_erb_each_request
|
|
288
357
|
( @erb_cache[ path_for( klass, view ) ] ||= ERB.new( IO.readlines( erb_filename( klass, view ) ).join ) ).result( _binding )
|
|
289
358
|
end
|
|
290
359
|
|
|
@@ -294,37 +363,34 @@ class View
|
|
|
294
363
|
if klass.superclass
|
|
295
364
|
klass = klass.superclass
|
|
296
365
|
else
|
|
297
|
-
|
|
366
|
+
$LOG.warn "Not found #{path_for( klass, view)}"
|
|
367
|
+
raise WEBrick::HTTPStatus::NotFound
|
|
298
368
|
end
|
|
299
369
|
end
|
|
300
370
|
path_for( klass, view )
|
|
301
371
|
end
|
|
302
372
|
|
|
303
|
-
def path_for( klass, view ) "#{
|
|
373
|
+
def path_for( klass, view ) "#{view_folder}/#{klass}_#{view.downcase}.rhtml" end
|
|
304
374
|
|
|
305
375
|
def should_frame?( view )
|
|
306
|
-
|
|
376
|
+
not( dont_frame_views.include? view.downcase )
|
|
307
377
|
end
|
|
308
378
|
|
|
309
379
|
def frame_erb
|
|
310
|
-
@frame_erb = nil if
|
|
380
|
+
@frame_erb = nil if reload_erb_each_request
|
|
311
381
|
@frame_erb ||= load_frame_erb
|
|
312
382
|
end
|
|
313
383
|
|
|
314
384
|
def load_frame_erb
|
|
315
|
-
if File.exists? "#{
|
|
316
|
-
ERB.new( IO.readlines( "#{
|
|
385
|
+
if File.exists? "#{view_folder}/frame.rhtml"
|
|
386
|
+
ERB.new( IO.readlines( "#{view_folder}/frame.rhtml" ).join )
|
|
317
387
|
else
|
|
318
388
|
ERB.new( "<%= content_of_page %>" )
|
|
319
389
|
end
|
|
320
390
|
end
|
|
321
391
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
$SETTINGS
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
def method_missing( method, *args, &block )
|
|
392
|
+
def method_missing( method, *args, &block )
|
|
393
|
+
# $LOG.debug "View method missing called for #{method} with #{args.inspect}"
|
|
328
394
|
@wiki.send( method, *args, &block )
|
|
329
395
|
end
|
|
330
396
|
end
|
data/lib/soks.rb
CHANGED
|
@@ -9,35 +9,17 @@ require 'diff/lcs/array'
|
|
|
9
9
|
require 'fileutils'
|
|
10
10
|
require 'thread'
|
|
11
11
|
require 'yaml'
|
|
12
|
+
require 'logger'
|
|
12
13
|
|
|
13
14
|
require 'soks-utils'
|
|
14
15
|
require 'soks-storage'
|
|
15
16
|
require 'soks-model'
|
|
16
17
|
require 'soks-view'
|
|
17
18
|
require 'soks-servlet'
|
|
19
|
+
|
|
18
20
|
require 'helpers/default-helpers'
|
|
21
|
+
require 'helpers/maintenance-helpers'
|
|
22
|
+
require 'helpers/counter-helpers'
|
|
19
23
|
|
|
20
24
|
Thread.abort_on_exception = true
|
|
21
|
-
Socket.do_not_reverse_lookup = true
|
|
22
|
-
|
|
23
|
-
# These are the default settings. Can be overriden in the call to soks-servlet.rb#start_wiki
|
|
24
|
-
$SETTINGS = {
|
|
25
|
-
:name => 'A Soks Wiki',
|
|
26
|
-
:description => 'A Soks Wiki',
|
|
27
|
-
:root_directory => 'soks-wiki',
|
|
28
|
-
:check_files_every => 60, # Seconds
|
|
29
|
-
:url => 'http://localhost:8000',
|
|
30
|
-
:port => 8000,
|
|
31
|
-
:home_page => 'Home Page',
|
|
32
|
-
:dont_frame_templates => ['print','rss'],
|
|
33
|
-
:force_no_cache => false, # Adds headers to restrict the cacheing of pages
|
|
34
|
-
:redcloth_hard_breaks => false, # Set Redcloth to use hard breaks
|
|
35
|
-
:reload_erb_each_request => false, # False faster for production, true speeds development cycle
|
|
36
|
-
:server_type => WEBrick::SimpleServer, # Could be WEBrick::Daemon if you wish to fork
|
|
37
|
-
:authenticators => [ [ %r{/(view|rss|print|find|meta|attachment)/.*}, WEBrick::HTTPAuth::NoAuthenticationRequired.new ],
|
|
38
|
-
# [ %r{/upload/.*}, WEBrick::HTTPAuth::NotPermitted.new ],
|
|
39
|
-
# [ %r{/(edit|save)/home page}, WEBrick::HTTPAuth::SiteWidePassword.new('password','You need to enter the site wide password to edit the home page') ],
|
|
40
|
-
# [ %r{/(view|edit|save)/private.*},WEBrick::HTTPAuth::BasicAuth.new( :UserDB => htpasswd, :Realm => realm ) ], # See webrick documentation
|
|
41
|
-
[ %r{.*}, WEBrick::HTTPAuth::AskForUserName.new( 'No password, just enter a name') ]
|
|
42
|
-
]
|
|
43
|
-
}
|
|
25
|
+
Socket.do_not_reverse_lookup = true
|
|
@@ -3,7 +3,7 @@ function trim(str)
|
|
|
3
3
|
return str.replace(/^\s+/,'').replace(/\s+$/,'');
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
function editSelected()
|
|
6
|
+
function editSelected(web_root)
|
|
7
7
|
{
|
|
8
8
|
if (window.getSelection)
|
|
9
9
|
{
|
|
@@ -21,11 +21,11 @@ function editSelected()
|
|
|
21
21
|
void(txt=prompt('Please enter the title of the page you wish to create',''))
|
|
22
22
|
}
|
|
23
23
|
if(txt){
|
|
24
|
-
window.location =
|
|
24
|
+
window.location = web_root+escape(txt)
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function hotkey( event )
|
|
28
|
+
function hotkey( event, web_root )
|
|
29
29
|
{
|
|
30
30
|
event = (event) ? event : ((window.event) ? event : null);
|
|
31
31
|
if (event)
|
|
@@ -34,17 +34,8 @@ function hotkey( event )
|
|
|
34
34
|
{
|
|
35
35
|
var charCode = (event.charCode) ? event.charCode : ((event.which) ? event.which : event.keyCode);
|
|
36
36
|
if (charCode == 14 ) {
|
|
37
|
-
editSelected();
|
|
37
|
+
editSelected(web_root);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function validateTitle( proposed_title )
|
|
44
|
-
{
|
|
45
|
-
var illegalcharacters = /[\\\[\]\?<>&\^\/]/;
|
|
46
|
-
if (illegalcharacters.test( proposed_title ) == true )
|
|
47
|
-
{
|
|
48
|
-
alert( 'Unfortunately the characters \ / [ ] ? < > & ^ in titles cause problems with Soks. Please try not to use them.');
|
|
49
|
-
}
|
|
50
41
|
}
|