Soks 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/LICENSE.txt +2 -0
  2. data/README.txt +3 -2
  3. data/TODO.txt +31 -0
  4. data/bin/soks-create-wiki.rb +0 -1
  5. data/lib/authenticators.rb +30 -4
  6. data/lib/helpers/counter-helpers.rb +132 -0
  7. data/lib/helpers/default-helpers.rb +170 -169
  8. data/lib/helpers/mail2wiki-helper.rb +18 -22
  9. data/lib/helpers/maintenance-helpers.rb +149 -0
  10. data/lib/helpers/rss2wiki-helper.rb +7 -8
  11. data/lib/soks-model.rb +82 -54
  12. data/lib/soks-servlet.rb +126 -108
  13. data/lib/soks-storage.rb +74 -11
  14. data/lib/soks-utils.rb +77 -3
  15. data/lib/soks-view.rb +169 -103
  16. data/lib/soks.rb +5 -23
  17. data/templates/default/attachment/newpage.js +4 -13
  18. data/templates/default/attachment/print_stylesheet.css +2 -7
  19. data/templates/default/caches/readme.txt +1 -0
  20. data/templates/default/content/Api%20for%20classes%20to%20modify%20the%20wiki.textile +2 -0
  21. data/templates/default/content/Author.textile +4 -1
  22. data/templates/default/content/Automatic%20Summaries.textile +16 -53
  23. data/templates/default/content/Automatic%20linking%20between%20pages.textile +3 -3
  24. data/templates/default/content/{bug%3A%20competing%20edits.textile → Bug%3A%20Competing%20edits.textile} +9 -0
  25. data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +2 -0
  26. data/templates/default/content/Bug%3A%20E%2Dmail%20addresses%20with%20hyphens%20not%20recognised.textile +17 -0
  27. data/templates/default/content/Bug%3A%20Email%20adresses%20in%20page%20titles%20cause%20incorrec.textile +3 -0
  28. data/templates/default/content/Bug%3A%20GEM%20limits%20title%20lengths.textile +3 -1
  29. data/templates/default/content/Bug%3A%20Memory%20leak.textile +13 -0
  30. data/templates/default/content/Bug%3A%20Pages%20that%20link%20here%20may%20not%20appear%20on%20r.textile +13 -0
  31. data/templates/default/content/Bug%3A%20Textile%20mishandles%20paragraphs.textile +4 -0
  32. data/templates/default/content/Bug%3A%20Unanticipated%20Rollbacks.textile +2 -0
  33. data/templates/default/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +2 -0
  34. data/templates/default/content/Home%20Page.textile +3 -1
  35. data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +23 -13
  36. data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +3 -1
  37. data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +22 -0
  38. data/templates/default/content/How%20to%20get%20the%20latest%20Soks%20from%20cvs.textile +2 -0
  39. data/templates/default/content/How%20to%20hack%20soks.textile +2 -0
  40. data/templates/default/content/How%20to%20import%20a%20site%20from%20instiki.textile +2 -0
  41. data/templates/default/content/{How%20to%20import%20data%20to%20this%20wiki.textile → How%20to%20import%20data.textile} +3 -7
  42. data/templates/default/content/How%20to%20install%20Soks.textile +2 -0
  43. data/templates/default/content/How%20to%20password%20protect%20your%20wiki.textile +21 -11
  44. data/templates/default/content/How%20to%20report%20a%20bug.textile +2 -1
  45. data/templates/default/content/How%20to%20upgrade%20soks.textile +22 -0
  46. data/templates/default/content/How%20to%20use%20the%20keyboard%20shortcuts.textile +2 -2
  47. data/templates/default/content/How%20to%20use%20this%20wiki.textile +3 -1
  48. data/templates/default/content/List%20of%20changes.textile +84 -118
  49. data/templates/default/content/News%3A%20Version%201%2D0%2D0%20released.textile +19 -0
  50. data/templates/default/content/Pages%20to%20include%20in%20the%20distribution.textile +51 -0
  51. data/templates/default/content/Per%20Wiki%20Templates.textile +2 -0
  52. data/templates/default/content/Planned%20Features.textile +30 -9
  53. data/templates/default/content/README.textile +3 -2
  54. data/templates/default/content/RSS%20feed.textile +1 -1
  55. data/templates/default/content/Recent%20changes%20to%20this%20site.textile +283 -0
  56. data/templates/default/content/SOKS%20features.textile +3 -0
  57. data/templates/default/content/Site%20Index.textile +202 -0
  58. data/templates/default/content/Soks%20Licence.textile +2 -0
  59. data/templates/default/content/Tag%3A%20Include%20this%20page%20in%20the%20distribution.textile +6 -0
  60. data/templates/default/start.rb +67 -123
  61. data/templates/default/version.txt +1 -1
  62. data/templates/default/views/Page_edit.rhtml +7 -7
  63. data/templates/default/views/{Page_search_results.rhtml → Page_find.rhtml} +9 -3
  64. data/templates/default/views/Page_linksfromrss.rhtml +24 -0
  65. data/templates/default/views/Page_listrss.rhtml +46 -0
  66. data/templates/default/views/Page_meta.rhtml +1 -1
  67. data/templates/default/views/Page_revision.rhtml +39 -0
  68. data/templates/default/views/Page_revisions.rhtml +13 -5
  69. data/templates/default/views/Page_rss.rhtml +8 -8
  70. data/templates/default/views/Page_view.rhtml +3 -3
  71. data/templates/default/views/UploadPage_edit.rhtml +8 -8
  72. data/templates/default/views/frame.rhtml +8 -8
  73. data/templates/default/views/messages.yaml +1 -0
  74. data/test/html/2006Mar.html +66 -0
  75. data/test/html/poignant.html +36 -0
  76. data/test/html/poignant.textile +36 -0
  77. data/test/mock-objects.rb +69 -0
  78. data/test/stress_url_calls.rb +33 -0
  79. data/test/stress_urls.txt +68 -0
  80. data/test/test_counter-helper.rb +158 -0
  81. data/test/test_soks-helper-maintenance.rb +106 -0
  82. data/test/test_soks-helpers.rb +104 -0
  83. data/test/test_soks-model.rb +144 -0
  84. data/test/test_soks-servlet.rb +231 -0
  85. data/test/test_soks-storage.rb +70 -31
  86. data/test/test_soks-utils.rb +112 -13
  87. data/test/test_soks-view.rb +141 -3
  88. metadata +38 -27
  89. data/templates/default/content/A%20page%20with%20an%20umlaut%20%F6%20in%20its%20title.textile +0 -1
  90. data/templates/default/content/All%20News.textile +0 -26
  91. data/templates/default/content/Bil%20Kleb.textile +0 -1
  92. data/templates/default/content/Bil.textile +0 -1
  93. data/templates/default/content/Bill%20Wood.textile +0 -3
  94. data/templates/default/content/Bug%3A%20RSS%20feed%20does%20not%20validate.textile +0 -10
  95. data/templates/default/content/Bug%3A%20Type%20a%20title%20here.textile +0 -31
  96. data/templates/default/content/Instructions%20and%20Howtos.textile +0 -21
  97. data/templates/default/content/Latest%20News.textile +0 -26
  98. data/templates/default/content/New%20Recent%20Changes%20class.textile +0 -68
  99. data/templates/default/content/New%20page%20templates%20or%20categories%20code.textile +0 -68
  100. data/templates/default/content/News%3A%20Version%200%2E0%2E6%20Released.textile +0 -13
  101. data/templates/default/content/Recent%20Blog%20Entries.textile +0 -5
  102. data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +0 -286
  103. data/templates/default/content/Ruby.textile +0 -9
  104. data/templates/default/content/Skorgu.textile +0 -3
  105. data/templates/default/content/ctrl%2Dn.textile +0 -1
  106. data/templates/default/content/let%20me%20know.textile +0 -1
  107. data/templates/default/content/sandbox.textile +0 -20
  108. data/templates/default/content/tamc.textile +0 -1
  109. 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
- def url( name, view = 'view' )
5
- "#{$SETTINGS[:url]}/#{view}/#{name}"
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
- "#{$SETTINGS[:url]}/attachment/#{name}"
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 = /\b#{Regexp.escape(title)}\b/i
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, :textile, :markdown, :inline_soks ]
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 ), [ :no_span_caps])
107
- self.hard_breaks = true if $SETTINGS[:redcloth_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 |m|
153
- unless @wiki.exists? $1 # So we don't accidentlaly match a page whose name starts 'insert'
154
- inserted_page = @wiki.page( $2 )
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
- m
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
- when /[A-Za-z0-9.]+?@[A-Za-z0-9.]+/ ; link("mailto:#{pagename}",title)
181
- when /^http:\/\//i ; link(pagename,title)
182
- else ; wiki_link( pagename, title )
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 ) { |title, page| wiki_link( page.name, title, 'automatic' ) }
189
- end
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
- def url_for( pagename, view = 'view' )
204
- view, pagename = $1, $2 if pagename =~ /\/(\w+)\/(.*)/
205
- "#{$SETTINGS[:url]}/#{view}/#{pagename}"
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
- attr_reader :rollingmatch, :links
307
+ REDCLOTH_CACHE_NAME = 'redcloth'
215
308
 
216
- def initialize( wiki, name )
217
- @wikiname = name
218
- @rollingmatch, @links, @redcloth_cache, @erb_cache = BruteMatch.new, Links.new, Hash.new, Hash.new
219
- @wiki = wiki
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 view( pagename, view = 'view', person = nil )
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 binding
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] = "" if page.textile.strip == ""
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
- @redcloth_cache[page] = "" if page.textile.strip == ""
279
- @redcloth_cache[ page ] ||= WikiRedCloth.new( self, page, page.textile ).to_html
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 $SETTINGS[:reload_erb_each_request]
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
- raise WEBrick::HTTPStatus::NotFound
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 ) "#{$SETTINGS[:root_directory]}/views/#{klass}_#{view}.rhtml" end
373
+ def path_for( klass, view ) "#{view_folder}/#{klass}_#{view.downcase}.rhtml" end
304
374
 
305
375
  def should_frame?( view )
306
- return true unless $SETTINGS[:dont_frame_templates].include? view.downcase
376
+ not( dont_frame_views.include? view.downcase )
307
377
  end
308
378
 
309
379
  def frame_erb
310
- @frame_erb = nil if $SETTINGS[:reload_erb_each_request]
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? "#{$SETTINGS[:root_directory]}/views/frame.rhtml"
316
- ERB.new( IO.readlines( "#{$SETTINGS[:root_directory]}/views/frame.rhtml" ).join )
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
- # CGI and FCGI can't access this global directly, so call through here
323
- def settings
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 = '/edit/'+escape(trim(txt))
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
  }