Soks 0.0.6 → 0.0.7

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.
Files changed (44) hide show
  1. data/README.txt +4 -0
  2. data/lib/helpers/default-helpers.rb +94 -56
  3. data/lib/helpers/mail2wiki-helper.rb +8 -6
  4. data/lib/soks-servlet.rb +19 -16
  5. data/lib/soks-storage.rb +6 -7
  6. data/lib/soks-utils.rb +26 -0
  7. data/lib/soks-view.rb +4 -4
  8. data/lib/soks.rb +2 -1
  9. data/templates/default/attachment/newpage.js +2 -2
  10. data/templates/default/attachment/stylesheet.css +14 -3
  11. data/templates/default/content/A%20page%20with%20an%20umlaut%20%F6%20in%20its%20title.textile +1 -0
  12. data/templates/default/content/All%20News.textile +18 -1
  13. data/templates/default/content/Bil%20Kleb.textile +1 -0
  14. data/templates/default/content/Bil.textile +1 -0
  15. data/templates/default/content/Bill%20Wood.textile +3 -0
  16. data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +1 -0
  17. data/templates/default/content/Bug%3A%20Type%20a%20title%20here.textile +31 -0
  18. data/templates/default/content/How%20to%20use%20the%20keyboard%20shortcuts.textile +4 -2
  19. data/templates/default/content/Latest%20News.textile +19 -2
  20. data/templates/default/content/List%20of%20changes.textile +43 -0
  21. data/templates/default/content/New%20Recent%20Changes%20class.textile +10 -0
  22. data/templates/default/content/News%3A%20Version%200%2E0%2E6%20Released.textile +13 -0
  23. data/templates/default/content/Planned%20Features.textile +9 -8
  24. data/templates/default/content/README.textile +4 -0
  25. data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +282 -205
  26. data/templates/default/content/Skorgu.textile +3 -0
  27. data/templates/default/content/ctrl%2Dn.textile +1 -1
  28. data/templates/default/content/sandbox.textile +20 -0
  29. data/templates/default/start.rb +15 -5
  30. data/templates/default/version.txt +1 -1
  31. data/templates/default/views/Page_edit.rhtml +6 -3
  32. data/templates/default/views/frame.rhtml +3 -2
  33. data/test/test_soks-storage.rb +69 -0
  34. data/test/test_soks-utils.rb +84 -0
  35. data/test/test_soks-view.rb +43 -0
  36. metadata +14 -11
  37. data/templates/default/content/Attached%20ruby%20logo.textile +0 -1
  38. data/templates/default/content/Attached%20test%20thing.textile +0 -1
  39. data/templates/default/content/Known%20bugs.textile +0 -18
  40. data/templates/default/content/Picture%20of%20Type%20a%20title%20here.textile +0 -1
  41. data/templates/default/content/Picture%20of%20a%20logo%20for%20the%20ruby%20language.textile +0 -1
  42. data/templates/default/content/Picture%20of%20powered%20by%20ruby%20logo.textile +0 -1
  43. data/templates/default/content/Recent%20News.textile +0 -9
  44. data/templates/default/content/Type%20a%20title%20here.textile +0 -1
data/README.txt CHANGED
@@ -44,6 +44,8 @@ h2. UPGRADE
44
44
 
45
45
  If you already have a previous version of soks then to upgrade, run @soks-create-wiki.rb --destination-dir=path/to/your/wiki@ and it will guide you through the upgrade.
46
46
 
47
+ Note that if you were using the multi page index class before, you will need to manually delete all the old index pages (@rm content/Site%20Index*@). The new pages will be created automatically.
48
+
47
49
  h2. FEATURES
48
50
 
49
51
  # Runs on its own webrick server (no independent web server required)
@@ -62,11 +64,13 @@ I suspect there are many, as befits its version number. In particular it has:
62
64
  * Does not permit browsers to cache pages
63
65
  * Not user friendly in the way it handles simultaneous edits of a page (last person to save wins)
64
66
  * Some bugs in layout and formatting of text.
67
+ * RSS feed does not completely validate
65
68
 
66
69
  See http://www.soks.org/wiki/KnownBugs for details.
67
70
 
68
71
  h2. RELEASES
69
72
 
73
+ # 2005 Mar 21 - soks-0.0.7 - Fifth public release (alpha)
70
74
  # 2005 Mar 15 - soks-0.0.6 - Fourth public release (alpha)
71
75
  # 2005 Feb 12 - soks-0.0.5 - Third public release (alpha)
72
76
  # 2005 Jan 24 - soks-0.0.4 - Second public release (alpha)
@@ -48,9 +48,12 @@ end
48
48
  class AutomaticSummary
49
49
 
50
50
  DEFAULT_SETTINGS = {
51
- :regexp_for_title => /.*/, # These three regexps act as an AND
51
+ :regexp_for_title => /.*/, # These six regexps act as an AND, with the exclude three acting as NOT their contents
52
52
  :regexp_for_author => nil,
53
53
  :regexp_for_content => nil,
54
+ :regexp_to_exclude_title => nil,
55
+ :regexp_to_exclude_author => nil,
56
+ :regexp_to_exclude_content => nil,
54
57
  :max_pages_to_show => nil,
55
58
  :pagename => 'Summary',
56
59
  :author => 'AutomaticSummary',
@@ -61,6 +64,7 @@ class AutomaticSummary
61
64
  :include_metadata => false, # Includes author and time in summary
62
65
  :summarise_revisions => false, # If true, then can contain several revisions for same page
63
66
  :remove_deleted_pages => true, # If false will keep references to deleted pages
67
+ :merge_revisions => false, # If true, repeats with the same author will be merged
64
68
  }
65
69
 
66
70
  attr_reader :settings, :pages_in_summary
@@ -70,53 +74,72 @@ class AutomaticSummary
70
74
  setup_list
71
75
  scan_for_pages_to_summarise_in wiki
72
76
  render_summary
73
- start_watching_wiki wiki
77
+ start_watching wiki
74
78
  end
75
79
 
76
80
  def check_whether_to_add_page( page, revision )
77
- return if page.name == @settings[:pagename]
78
- if summarise? page
79
- @pages_in_summary.add( @settings[:summarise_revisions] ? revision : page )
80
- render_summary
81
- end
81
+ return unless summarise?( page )
82
+ remove_previous_revisions( page, revision ) if @settings[:merge_revisions]
83
+ @pages_in_summary.add( @settings[:summarise_revisions] ? revision : page )
84
+ render_summary
82
85
  end
83
86
 
84
87
  def check_whether_to_remove_page( page, revision )
85
88
  return unless @settings[:remove_deleted_pages]
86
- render_summary if @pages_in_summary.remove( @settings[:summarise_revisions] ? revision : page )
89
+ return unless summarise?( page )
90
+ return unless @pages_in_summary.remove( @settings[:summarise_revisions] ? revision : page )
91
+ render_summary
87
92
  end
88
93
 
89
94
  private
90
95
 
91
96
  def summarise?( page )
97
+ return false if page.name == @settings[:pagename]
92
98
  return false if @settings[:regexp_for_title] && page.name !~ @settings[:regexp_for_title]
93
99
  return false if @settings[:regexp_for_author] && page.author !~ @settings[:regexp_for_author]
94
100
  return false if @settings[:regexp_for_content] && page.content !~ @settings[:regexp_for_content]
101
+ return false if @settings[:regexp_to_exclude_title] && page.name =~ @settings[:regexp_to_exclude_title]
102
+ return false if @settings[:regexp_to_exclude_author] && page.author =~ @settings[:regexp_to_exclude_author]
103
+ return false if @settings[:regexp_to_exclude_content] && page.content =~ @settings[:regexp_to_exclude_content]
95
104
  return true
96
105
  end
97
106
 
98
107
  def scan_for_pages_to_summarise_in( wiki )
99
108
  wiki.each( @settings[:remove_deleted_pages] ) do |name,page|
100
- next if page.name == @settings[:pagename]
101
- next unless summarise? page
102
109
  if @settings[:summarise_revisions]
103
- page.revisions.each { |revision| @pages_in_summary.add revision }
110
+ scan_for_revisions_to_summarise_in( page )
104
111
  else
112
+ next unless summarise? page
105
113
  @pages_in_summary.add page
106
114
  end
107
115
  end
108
116
  end
109
117
 
110
- def render_summary
111
- if @wiki.exists? @settings[:pagename]
112
- old_page = @wiki.page( @settings[:pagename] )
113
- if old_page.textile =~ /(.*?<automaticsummary>).*?(<\/automaticsummary>.*)/mi
114
- content, tail = $1, $2
115
- end
118
+ def scan_for_revisions_to_summarise_in( page )
119
+ page.revisions.each do |revision|
120
+ next unless summarise? revision
121
+ remove_previous_revisions( page, revision ) if @settings[:merge_revisions]
122
+ @pages_in_summary.add revision
116
123
  end
117
- content ||= "h2. #{@settings[:pagename]}\n\np{font-size: x-small;}. #{@settings[:pagename]} was created automatically from pages whose title matches ==#{@settings[:regexp_for_title].inspect}==.\n\n<automaticsummary>"
118
- tail ||= "</automaticsummary>"
119
- content << "\n\n"
124
+ end
125
+
126
+ def remove_previous_revisions( page, revision )
127
+ revision.number.downto(0) do |previous_number|
128
+ previous_revision = page.revisions.at( previous_number )
129
+ break unless previous_revision.author == revision.author
130
+ @pages_in_summary.remove( previous_revision )
131
+ end
132
+ end
133
+
134
+ def render_summary
135
+ @wiki.page( @settings[:pagename] ).textile =~ /(.*?<automaticsummary>).*?(<\/automaticsummary>.*)/mi
136
+ top = $1 || "h2. #{@settings[:pagename]}\n\np{font-size: x-small;}. #{@settings[:pagename]} was created automatically from pages whose title matches ==#{@settings[:regexp_for_title].inspect}==.\n\n<automaticsummary>"
137
+ tail = $2 || "</automaticsummary>"
138
+ @wiki.revise( @settings[:pagename], top + render_list + tail , @settings[:author] )
139
+ end
140
+
141
+ def render_list
142
+ content = "\n\n"
120
143
  if @pages_in_summary.empty?
121
144
  content << "No pages found to summarise"
122
145
  elsif @renderer
@@ -127,12 +150,10 @@ class AutomaticSummary
127
150
  @pages_in_summary.each { |page| content << render_link_to(page) }
128
151
  end
129
152
  content << "\n\n"
130
- content << tail
131
- @wiki.revise( @settings[:pagename], content , @settings[:author] )
132
153
  end
133
154
 
134
155
  def render_page( page )
135
- "<div class='subpage'>\n[[#{page.name}]] #{ @settings[:include_metadata] ? render_meta_data( page ) : "" }<br />\n\n#{page.textile.first_lines( @settings[:lines_to_include] ).close_unmatched_html}\n\np(more). [[(more) => #{page.name}]]\n\n</div>\n"
156
+ "<div class='subpage'>\n[[ #{page.name} ]] #{ @settings[:include_metadata] ? render_meta_data( page ) : "" }<br />\n\n#{page.textile.first_lines( @settings[:lines_to_include] ).close_unmatched_html}\n\np(more). [[(more) => #{page.name}]]\n\n</div>\n"
136
157
  end
137
158
 
138
159
  def render_link_to( page )
@@ -144,42 +165,57 @@ class AutomaticSummary
144
165
  end
145
166
 
146
167
  def setup_list
147
- @pages_in_summary = FiniteUniqueList.new( @settings[:max_pages_to_show],
148
- @settings[:reverse_sort],
149
- @settings[:sort_pages_by] )
168
+ @pages_in_summary = FiniteUniqueList.new( @settings[:max_pages_to_show], @settings[:reverse_sort], @settings[:sort_pages_by] )
150
169
  end
151
170
 
152
- def start_watching_wiki( wiki )
171
+ def start_watching( wiki )
153
172
  wiki.watch_for( @settings[:only_new_pages] == true ? :page_created : :page_revised ) { |event, page, revision| check_whether_to_add_page( page, revision ) }
154
173
  wiki.watch_for( :page_deleted ) { |event, page, revision| check_whether_to_remove_page( page, revision ) } if @settings[:remove_deleted_pages]
155
174
  end
156
175
 
157
- end
176
+ end
158
177
 
159
- class AutomaticRecentChanges
178
+ class AutomaticRecentChanges < AutomaticSummary
179
+
180
+ def initialize( wiki, changes = 200, title_regexp = /.*/, pagename = "Recent Changes to This Site", author = "AutomaticRecentChanges", exclude_automatic_helpers = true, merge_revisions = true )
181
+ super( wiki, { :pagename => pagename,
182
+ :regexp_for_title => title_regexp,
183
+ :regexp_to_exclude_author => exclude_automatic_helpers && /^Automatic/i,
184
+ :max_pages_to_show => changes,
185
+ :author => author,
186
+ :only_new_pages => false,
187
+ :sort_pages_by => :revised_on,
188
+ :summarise_revisions => true,
189
+ :reverse_sort => true,
190
+ :remove_deleted_pages => false,
191
+ :merge_revisions => merge_revisions,
192
+ } )
193
+ end
160
194
 
161
- def initialize( wiki, changes = 200, pagename = "Recent Changes to This Site", author = "AutomaticRecentChanges" )
162
- AutomaticSummary.new( wiki, { :pagename => pagename,
163
- :max_pages_to_show => changes,
164
- :author => author,
165
- :only_new_pages => false,
166
- :sort_pages_by => :revised_on,
167
- :include_metadata => true,
168
- :summarise_revisions => true,
169
- :reverse_sort => true,
170
- :remove_deleted_pages => false,
171
- } )
195
+ def render_list
196
+ content = "<div class='recentchanges'>\n\nh2. Today\n\n"
197
+ previous_time = Time.now
198
+ @pages_in_summary.each do |revision|
199
+ unless revision.revised_on.same_day?( previous_time )
200
+ content << "\nh2. #{revision.revised_on.strftime('%a %d %b %Y')}\n\n"
201
+ previous_time = revision.revised_on
202
+ end
203
+ content << "* #{revision.revised_on.strftime('%H:%M')} - [[#{revision.name}]] revised by #{revision.author}\n"
204
+ end
205
+ content << "\n\n</div>"
172
206
  end
207
+
173
208
  end
174
209
 
175
210
  class AutomaticOnePageIndex
176
211
 
177
212
  def initialize( wiki, pagename = "Site Index", author = "AutomaticIndex" )
178
213
  AutomaticSummary.new( wiki, { :pagename => pagename,
179
- :author => author,
180
- :only_new_pages => true,
181
- :sort_pages_by => :name_for_index,
182
- } )
214
+ :regexp_to_exclude_title => /#{Regexp.escape(pagename)}/i,
215
+ :author => author,
216
+ :only_new_pages => true,
217
+ :sort_pages_by => :name_for_index,
218
+ } )
183
219
  end
184
220
 
185
221
  end
@@ -190,20 +226,22 @@ class AutomaticMultiPageIndex
190
226
  content = "h1. #{pageroot}\n\n"
191
227
  ('A'..'Z').each do |letter|
192
228
  AutomaticSummary.new( wiki, { :regexp_for_title => /^#{letter}.*/i,
193
- :pagename => "#{pageroot} #{letter}",
194
- :author => author,
195
- :only_new_pages => true,
196
- :sort_pages_by => :name_for_index,
197
- } )
198
- content << "* #{pageroot} #{letter}\n"
229
+ :pagename => "#{pageroot} #{letter}.",
230
+ :regexp_to_exclude_title => /^#{Regexp.escape(pageroot)} ([a-z]|Other)\./i,
231
+ :author => author,
232
+ :only_new_pages => true,
233
+ :sort_pages_by => :name_for_index,
234
+ } )
235
+ content << "* #{pageroot} #{letter}.\n"
199
236
  end
200
237
  AutomaticSummary.new( wiki, { :regexp_for_title => /^[^A-Za-z].*/,
201
- :pagename => "#{pageroot} Other",
202
- :author => author,
203
- :only_new_pages => true,
204
- :sort_pages_by => :name_for_index,
205
- } )
206
- content << "* #{pageroot} Other\n"
238
+ :pagename => "#{pageroot} Other.",
239
+ :regexp_to_exclude_title => /^#{Regexp.escape(pageroot)} ([a-z]|Other)\./i,
240
+ :author => author,
241
+ :only_new_pages => true,
242
+ :sort_pages_by => :name_for_index,
243
+ } )
244
+ content << "* #{pageroot} Other.\n"
207
245
  wiki.revise( pageroot, content, author )
208
246
  end
209
247
 
@@ -1,5 +1,12 @@
1
1
  require 'net/imap'
2
2
 
3
+ # From Dave Burt on comp.lang.ruby
4
+ class String
5
+ def from_quoted_printable
6
+ self.gsub(/\r\n/, "\n").unpack("M").first
7
+ end
8
+ end
9
+
3
10
  class Message
4
11
 
5
12
  attr_reader :message_id, :subject, :sender_name, :sender_email, :date, :text
@@ -15,12 +22,7 @@ class Message
15
22
  end
16
23
 
17
24
  def plain_text_content_from_message( id )
18
- text = @imap.fetch( id, 'BODY[1]' ).first.attr['BODY[1]']
19
- text.gsub!(/\r\n/,"\n")
20
- text.gsub!(/\r/,"\n")
21
- text.gsub!(/=\n/,'')
22
- #text.gsub!(/((?:=[0-9a-fA-F]{2})+)/n) { [$1.delete('=')].pack('H*') }
23
-
25
+ text = @imap.fetch( id, 'BODY[1]' ).first.attr['BODY[1]'].from_quoted_printable
24
26
  text
25
27
  end
26
28
 
data/lib/soks-servlet.rb CHANGED
@@ -16,7 +16,8 @@ class WikiServlet < WEBrick::HTTPServlet::AbstractServlet
16
16
  doAttachment( request, response, request.path[1..-1] )
17
17
  when /\/(\w+?)\/(.+)/ # If request of the form /verb/pagename then doVerb on this class
18
18
  verb, pagename = $1, make_pagename_valid( $2 )
19
- authenticate request, response
19
+ authenticate request, response
20
+ make_username_valid( request )
20
21
  if self.respond_to?( "do#{verb.capitalize}" )
21
22
  self.send( "do#{verb.capitalize}", request, response, pagename, request.user )
22
23
  else
@@ -108,22 +109,21 @@ class WikiServlet < WEBrick::HTTPServlet::AbstractServlet
108
109
 
109
110
  def upload_file_data( upload_data )
110
111
  path = "#{$SETTINGS[:root_directory]}/attachment/"
111
- filename = unique_filename( path , upload_data.filename )
112
+ filename = File.unique_filename( path , upload_data.filename )
112
113
  File.open( File.join( path, filename ), 'wb' ) { |file| upload_data.list.each { |data| file << data } }
113
114
  "/attachment/#{filename}"
114
115
  end
115
116
 
116
- def unique_filename( path, filename )
117
- filename.gsub!(' ','') # Unfortunately no spaces permitted in redcloth links
118
- return filename unless File.exist? File.join( path, filename ) # Leave as is, if doesn't exist
119
- name, counter, extension = File.basename( filename, '.*'), 1, File.extname( filename )
120
- counter += 1 while File.exist? File.join( path, "#{name}#{counter}#{extension}" )
121
- return "#{name}#{counter}#{extension}"
122
- end
123
-
124
117
  # Certain characters cause problems in titles, so delete
125
118
  def make_pagename_valid( pagename )
126
- pagename.tr('\[]?{}&^`<>','')
119
+ pagename.to_valid_pagename
120
+ end
121
+
122
+ # Because the username is also used as a page title, also delete troublesome characters from them
123
+ # and make sure the name doesn't start with Automatic
124
+ def make_username_valid( request )
125
+ request.user = request.user.to_valid_pagename
126
+ request.user = "External #{request.user}" if request.user =~ /^Automatic/i
127
127
  end
128
128
  end
129
129
 
@@ -134,23 +134,26 @@ def start_wiki( settings = {}, &automatic_agents )
134
134
 
135
135
  wiki = Wiki.new( "#{$SETTINGS[:root_directory]}/content" )
136
136
  view = View.new( wiki, $SETTINGS[:name] )
137
-
137
+
138
138
  Thread.new( automatic_agents, wiki, view ) do |block, wiki, view|
139
+ $LOG.info "Starting helper classes"
139
140
  block.call( wiki, view )
141
+ $LOG.info "Finished starting helper classes"
140
142
  end.priority = -2
141
143
 
142
144
  server = WEBrick::HTTPServer.new( { :Port => $SETTINGS[:port],
143
- :ServerType=> $SETTINGS[:server_type]
144
- } )
145
+ :ServerType=> $SETTINGS[:server_type]
146
+ } )
145
147
 
146
148
  server.mount("/", WikiServlet, view, $SETTINGS )
147
149
 
148
150
  trap("INT") {
149
- $stderr.puts "Trying to shutdown gracefully"
151
+ $LOG.warn "Trying to shutdown gracefully"
150
152
  server.shutdown
151
153
  wiki.shutdown
152
- $stderr.puts "Shutdown."
154
+ $LOG.info "Shutdown."
153
155
  }
154
156
 
157
+ $LOG.warn "Starting server"
155
158
  server.start
156
159
  end
data/lib/soks-storage.rb CHANGED
@@ -2,7 +2,7 @@ module WikiFlatFileStore
2
2
 
3
3
  CONTENT_EXTENSION = '.textile'
4
4
  REVISIONS_EXTENSION = '.yaml'
5
- DEFAULT_AUTHOR = 'AutomaticImport'
5
+ DEFAULT_AUTHOR = 'the import script'
6
6
 
7
7
  def load_all_pages
8
8
  move_files_if_names_are_not_url_encoded
@@ -64,9 +64,9 @@ module WikiFlatFileStore
64
64
  revisions[ array[0] ] = Revision.new( page, *array ) }
65
65
  }
66
66
  rescue
67
- $stderr.puts "Error loading revisions with #{$!.to_s} in file #{page.name}"
67
+ $LOG.error "Error loading revisions with #{$!.to_s} in file #{page.name}"
68
68
  end
69
- revisions.each_with_index { |r,i| $stderr.puts "#{page.name} missing revision #{i}" unless r }
69
+ revisions.each_with_index { |r,i| $LOG.error "#{page.name} missing revision #{i}" unless r }
70
70
  revisions
71
71
  end
72
72
 
@@ -84,8 +84,8 @@ module WikiFlatFileStore
84
84
  def move_files_if_names_are_not_url_encoded
85
85
  Dir[ File.join( @folder, "*#{CONTENT_EXTENSION}" ) ].each do |filename|
86
86
  basename = File.basename( filename, '.*')
87
- next if basename.url_decode.url_encode == basename # All ok, so no worry
88
- new_name = File.join( File.dirname(filename), basename.url_decode.url_encode) + File.extname( filename)
87
+ next if basename.url_decode.to_valid_pagename.url_encode == basename # All ok, so no worry
88
+ new_name = File.join( File.dirname(filename), File.unique_filename( File.dirname(filename), basename.url_decode.to_valid_pagename.url_encode + File.extname( filename) ) )
89
89
  File.rename(filename, new_name )
90
90
  end
91
91
  end
@@ -102,14 +102,13 @@ module WikiFlatFileStore
102
102
 
103
103
  # Appends the last revision onto the yaml file
104
104
  def save_revisions( page )
105
- $stderr.puts "Saving revisions for #{page.name}"
105
+ $LOG.info "Saving revisions for #{page.name}"
106
106
  File.open(filename_for_revisions( page.name ), 'a' ) do |file|
107
107
  YAML.dump( page.revisions.last.to_a, file )
108
108
  file.puts # Needed to ensure that documents are separated
109
109
  end
110
110
  end
111
111
 
112
-
113
112
  def page_name_for( filename )
114
113
  File.basename( filename, '.*').url_decode
115
114
  end
data/lib/soks-utils.rb CHANGED
@@ -143,6 +143,11 @@ class String
143
143
  end
144
144
  text
145
145
  end
146
+
147
+ # Removes punctuation and spaces that can cause problems with page names
148
+ def to_valid_pagename
149
+ self.tr('\\\[]?{}&^`<>/','').strip
150
+ end
146
151
  end
147
152
 
148
153
  class FiniteUniqueList
@@ -217,3 +222,24 @@ class Numeric
217
222
  end
218
223
  end
219
224
 
225
+ class Time
226
+
227
+ # Checks whether two times are on the same day
228
+ def same_day?( other_time )
229
+ return false unless other_time.year == self.year
230
+ return false unless other_time.yday == self.yday
231
+ return true
232
+ end
233
+ end
234
+
235
+ class File
236
+
237
+ def self.unique_filename( path, filename )
238
+ filename.tr!(' ','') # Unfortunately no spaces permitted in redcloth links
239
+ return filename unless exist?( join( path, filename ) )# Leave as is, if doesn't exist
240
+ name, counter, extension = basename( filename, '.*'), 1, extname( filename )
241
+ counter += 1 while exist?( join( path, "#{name}#{counter}#{extension}" ) )
242
+ return "#{name}#{counter}#{extension}"
243
+ end
244
+
245
+ end
data/lib/soks-view.rb CHANGED
@@ -71,7 +71,7 @@ class BruteMatch
71
71
 
72
72
  def match( text )
73
73
  @titles.each do |title|
74
- regexp = /#{Regexp.escape(title)}/i
74
+ regexp = /\b#{Regexp.escape(title)}\b/i
75
75
  page = @matches[ title ]
76
76
  text.gsub!( regexp ) { |match| yield match, page }
77
77
  end
@@ -222,7 +222,7 @@ class View
222
222
 
223
223
  def view( pagename, view = 'view', person = nil )
224
224
  page = @wiki.page pagename
225
- renderedview = redcloth( page )
225
+ renderedview = redcloth( page )
226
226
  content_of_page = html( page.class, view, binding )
227
227
  if should_frame? view
228
228
  frame_erb.result binding
@@ -269,7 +269,7 @@ class View
269
269
  end
270
270
 
271
271
  def refresh_redcloth( page )
272
- $stderr.puts "Refreshing #{page}"
272
+ $LOG.info "Refreshing #{page}"
273
273
  @redcloth_cache[page] = "" if page.textile.strip == ""
274
274
  @redcloth_cache[ page ] = WikiRedCloth.new( self, page, page.textile ).to_html
275
275
  end
@@ -289,7 +289,7 @@ class View
289
289
  end
290
290
 
291
291
  def erb_filename( klass, view )
292
- $stderr.puts "Looking for #{path_for( klass, view)}"
292
+ $LOG.info "Looking for #{path_for( klass, view)}"
293
293
  until File.exists?( path_for( klass, view ) )
294
294
  if klass.superclass
295
295
  klass = klass.superclass
data/lib/soks.rb CHANGED
@@ -32,11 +32,12 @@ $SETTINGS = {
32
32
  :dont_frame_templates => ['print','rss'],
33
33
  :force_no_cache => false, # Adds headers to restrict the cacheing of pages
34
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
35
36
  :server_type => WEBrick::SimpleServer, # Could be WEBrick::Daemon if you wish to fork
36
37
  :authenticators => [ [ %r{/(view|rss|print|find|meta|attachment)/.*}, WEBrick::HTTPAuth::NoAuthenticationRequired.new ],
37
38
  # [ %r{/upload/.*}, WEBrick::HTTPAuth::NotPermitted.new ],
38
39
  # [ %r{/(edit|save)/home page}, WEBrick::HTTPAuth::SiteWidePassword.new('password','You need to enter the site wide password to edit the home page') ],
39
40
  # [ %r{/(view|edit|save)/private.*},WEBrick::HTTPAuth::BasicAuth.new( :UserDB => htpasswd, :Realm => realm ) ], # See webrick documentation
40
41
  [ %r{.*}, WEBrick::HTTPAuth::AskForUserName.new( 'No password, just enter a name') ]
41
- ]
42
+ ]
42
43
  }
@@ -42,9 +42,9 @@ function hotkey( event )
42
42
 
43
43
  function validateTitle( proposed_title )
44
44
  {
45
- var illegalcharacters = /[\\\[\]\?<>&\^]/;
45
+ var illegalcharacters = /[\\\[\]\?<>&\^\/]/;
46
46
  if (illegalcharacters.test( proposed_title ) == true )
47
47
  {
48
- alert( 'Unfortunately the characters \ [ ] ? < > & ^ in titles cause problems with Soks. Please try not to use them');
48
+ alert( 'Unfortunately the characters \ / [ ] ? < > & ^ in titles cause problems with Soks. Please try not to use them.');
49
49
  }
50
50
  }
@@ -159,6 +159,12 @@ pre.change {
159
159
  height: 75%;
160
160
  }
161
161
 
162
+
163
+ .help {
164
+ color: red;
165
+ text-align: center;
166
+ }
167
+
162
168
  #tips h1 {
163
169
  padding-left: 5px;
164
170
  margin-top: 0px;
@@ -178,6 +184,10 @@ form.editpage {
178
184
  display: inline;
179
185
  }
180
186
 
187
+ fieldset {
188
+ border: none;
189
+ }
190
+
181
191
  div.undochange {
182
192
  border-top: solid 1px #AAAAAA;
183
193
  margin-top: 10px;
@@ -199,7 +209,8 @@ div.undochange {
199
209
  margin-top: 5px;
200
210
  }
201
211
 
202
- .help {
203
- color: red;
204
- text-align: center;
212
+
213
+ .recentchanges li, .recentchanges ul {
214
+ list-style-type: none;
215
+ padding-left: 5px;
205
216
  }
@@ -4,6 +4,23 @@ p{font-size: x-small;}. All News was created automatically from pages whose titl
4
4
 
5
5
  <automaticsummary>
6
6
 
7
- No pages found to summarise
7
+ <div class='subpage'>
8
+ [[ News: Version 0.0.6 Released ]] <br />
9
+
10
+ It gives me great pleasure to announce version 0.0.6 of Soks - Yet another ruby wiki. You can get it from http://rubyforge.org/frs/?group_id=481&release_id=1807 or, if you have gems, run @sudo gem install Soks@.
11
+
12
+ This release fixes quite a lot of bugs, provides a few more settings that can be tweaked, and the default 'look' has been toned down. See list of changes for details, and please take a note of the known bugs.
13
+
14
+ Thanks to all those that helped with bugs, suggestions and code.
15
+
16
+ Grateful for feedback at tamc@rubyforge.org
17
+
18
+ *WARNING;* This Bug: Internet Exploror 6.0 incompatibilities during page edits is really annoying for users of IE 6. Temporary fixes can be found on that page, and I will make a new release soon to fix.
19
+
20
+
21
+ p(more). [[(more) => News: Version 0.0.6 Released]]
22
+
23
+ </div>
24
+
8
25
 
9
26
  </automaticsummary>
@@ -0,0 +1 @@
1
+ A steward of "FUN3D":http://fun3d.larc.nasa.gov software development at "NASA":http://www.larc.nasa.gov.
@@ -0,0 +1 @@
1
+ See Bil Kleb
@@ -0,0 +1,3 @@
1
+ Research Scientist at NASA Langley
2
+
3
+ A member of the "FUN3D":http://fun3d.larc.nasa.gov Software Development Team.
@@ -0,0 +1 @@
1
+ Currently tells the browser to not cache any page. This is wasteful of bandwidth and increases server load. Should handle the if-modified-since request headers to return 'not modified' messages instead.
@@ -0,0 +1,31 @@
1
+ Please click in the box above and give a meaningful title, then fill out any information below that you can. It is all optional, and I'm grateful for whatever you provide.
2
+
3
+ * Your name:
4
+ * Soks version:
5
+ * Your operating system:
6
+ * Your version of ruby:
7
+ * Your browser:
8
+
9
+ And please describe the problem below:
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+ And if you have any suggestions for the cause or a fix, please put it below:
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+ Thank you *very* much
30
+
31
+ tamc
@@ -2,7 +2,7 @@ h1. Keyboard Shortcuts
2
2
 
3
3
  Soks has a number of keyboard short cuts. Depending on your browser, only some of them will work:
4
4
 
5
- * ctrl-n : New page. Will use whatever text you had selected as the title of the new page (definitely only works on a few browsers)
5
+ * ctrl-n : New page. Will use whatever text you had selected as the title of the new page (definitely only works on a few browsers[1])
6
6
  * ctrl-e: Edit page, and if you are editing:
7
7
  ** ctrl-s saves the page
8
8
  ** ctrl-c cancels the editing
@@ -12,4 +12,6 @@ Soks has a number of keyboard short cuts. Depending on your browser, only some
12
12
  * ctrl-i: Site Index
13
13
  * ctrl-r: Recent changes to this site
14
14
 
15
- Note: on Linux/Firefox, substitute "meta" or "alt" for "ctrl".
15
+ *Note:* On Linux/Firefox and WindowsXP/IE6.0, substitute "meta" or "alt" for "ctrl". And for WindowsXP/IE6.0, these will only move you to the link on the page -- you then have to hit enter to proceed.
16
+
17
+ fn1. Does not work on Linux/Firefox1.0 or WindowsXP/IE6.0