Soks 0.0.2 → 0.0.3

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 (132) hide show
  1. data/README.txt +5 -4
  2. data/bin/soks-create-wiki.rb +153 -19
  3. data/contrib/easyprompt.rb +58 -0
  4. data/contrib/easyprompt_licence.txt +504 -0
  5. data/contrib/redcloth-2.0.11.rb +3 -1
  6. data/lib/authenticators.rb +18 -2
  7. data/lib/soks-helpers.rb +207 -157
  8. data/lib/soks-model.rb +131 -114
  9. data/lib/soks-servlet.rb +54 -35
  10. data/lib/soks-storage.rb +134 -0
  11. data/lib/soks-upgrade-0.0.2.rb +70 -0
  12. data/lib/soks-utils.rb +129 -19
  13. data/lib/soks-view.rb +136 -62
  14. data/lib/soks.rb +3 -1
  15. data/{template → templates/default}/attachment/logo.png +0 -0
  16. data/templates/default/attachment/logo.tiff +0 -0
  17. data/templates/default/attachment/newpage.js +41 -0
  18. data/templates/default/attachment/print_stylesheet.css +7 -0
  19. data/templates/default/attachment/rss.png +0 -0
  20. data/{template → templates/default}/attachment/stylesheet.css +44 -17
  21. data/templates/default/banned_titles.txt +31 -0
  22. data/templates/default/content/Bug%3A%20In%20a%20list%20of%20links%2C%20the%20last%20link%20is%20sometimes%20not%20linked.textile +10 -0
  23. data/templates/default/content/Bug%3A%20Symbols%20are%20not%20always%20correctly%20rendered%20in%20html.textile +3 -0
  24. data/templates/default/content/Bug%3A%20Uploads%20are%20not%20password%20protected.textile +3 -0
  25. data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +62 -0
  26. data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +30 -0
  27. data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +60 -0
  28. data/{template → templates/default}/content/How%20to%20hack%20soks.textile +3 -2
  29. data/{template → templates/default}/content/How%20to%20import%20a%20site%20from%20instiki.textile +1 -1
  30. data/templates/default/content/How%20to%20use%20this%20wiki.textile +27 -0
  31. data/templates/default/content/List%20of%20changes.textile +35 -0
  32. data/{template → templates/default}/content/Picture%20of%20a%20pair%20of%20soks.textile +0 -0
  33. data/{template → templates/default}/content/Soks%20Licence.textile +0 -0
  34. data/templates/default/content/home%20page.textile +17 -0
  35. data/templates/default/start.rb +94 -0
  36. data/templates/default/version.txt +1 -0
  37. data/{template → templates/default}/views/Page_content.rhtml +0 -0
  38. data/templates/default/views/Page_edit.rhtml +61 -0
  39. data/templates/default/views/Page_meta.rhtml +40 -0
  40. data/templates/default/views/Page_print.rhtml +6 -0
  41. data/templates/default/views/Page_revisions.rhtml +19 -0
  42. data/templates/default/views/Page_rss.rhtml +55 -0
  43. data/{template → templates/default}/views/Page_search_results.rhtml +1 -1
  44. data/templates/default/views/Page_view.rhtml +4 -0
  45. data/templates/default/views/UploadPage_edit.rhtml +38 -0
  46. data/templates/default/views/frame.rhtml +41 -0
  47. data/templates/default/views/messages.yaml +6 -0
  48. data/templates/instiki/attachment/header_backdrop.png +0 -0
  49. data/templates/instiki/attachment/instiki_style_sheet.css +199 -0
  50. data/templates/instiki/attachment/logo.tiff +0 -0
  51. data/templates/instiki/attachment/logotext.png +0 -0
  52. data/templates/instiki/attachment/newpage.js +41 -0
  53. data/templates/instiki/attachment/rss.png +0 -0
  54. data/templates/instiki/banned_titles.txt +31 -0
  55. data/templates/instiki/content/AutomaticSummary.textile +24 -0
  56. data/templates/instiki/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +60 -0
  57. data/templates/instiki/content/How%20to%20hack%20soks.textile +61 -0
  58. data/templates/instiki/content/How%20to%20import%20a%20site%20from%20instiki.textile +13 -0
  59. data/{template → templates/instiki}/content/Improving%20the%20style%20of%20this%20wiki.textile +2 -2
  60. data/templates/instiki/content/Known%20bugs.textile +8 -0
  61. data/templates/instiki/content/List%20of%20changes.textile +34 -0
  62. data/templates/instiki/content/Picture%20of%20a%20pair%20of%20soks.textile +1 -0
  63. data/templates/instiki/content/Pointers%20on%20adjusting%20the%20settings.textile +62 -0
  64. data/templates/instiki/content/Pointers%20on%20how%20to%20use%20this%20wiki.textile +27 -0
  65. data/templates/instiki/content/Recent%20Blog%20Entries.textile +3 -0
  66. data/templates/instiki/content/Recent%20Changes%20to%20This%20Site.textile +48 -0
  67. data/templates/instiki/content/Site%20Index.textile +16 -0
  68. data/templates/instiki/content/Soks%20Licence.textile +64 -0
  69. data/{template → templates/instiki}/content/home%20page.textile +9 -4
  70. data/templates/instiki/start.rb +85 -0
  71. data/templates/instiki/version.txt +1 -0
  72. data/templates/instiki/views/Page_content.rhtml +1 -0
  73. data/templates/instiki/views/Page_edit.rhtml +8 -0
  74. data/templates/instiki/views/Page_meta.rhtml +34 -0
  75. data/templates/instiki/views/Page_print.rhtml +6 -0
  76. data/templates/instiki/views/Page_revisions.rhtml +17 -0
  77. data/templates/instiki/views/Page_rss.rhtml +55 -0
  78. data/templates/instiki/views/Page_search_results.rhtml +18 -0
  79. data/templates/instiki/views/Page_view.rhtml +2 -0
  80. data/templates/instiki/views/UploadPage_edit.rhtml +16 -0
  81. data/templates/instiki/views/frame.rhtml +90 -0
  82. data/templates/instiki/views/messages.yaml +6 -0
  83. data/templates/rails/attachment/2colheader.css +77 -0
  84. data/templates/rails/attachment/basics.css +98 -0
  85. data/templates/rails/attachment/header_backdrop.png +0 -0
  86. data/templates/rails/attachment/logo.tiff +0 -0
  87. data/templates/rails/attachment/logotext.png +0 -0
  88. data/templates/rails/attachment/newpage.js +41 -0
  89. data/templates/rails/attachment/rss.png +0 -0
  90. data/templates/rails/banned_titles.txt +31 -0
  91. data/templates/rails/content/AutomaticSummary.textile +24 -0
  92. data/templates/rails/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +60 -0
  93. data/templates/rails/content/How%20to%20hack%20soks.textile +61 -0
  94. data/templates/rails/content/How%20to%20import%20a%20site%20from%20instiki.textile +13 -0
  95. data/templates/rails/content/Improving%20the%20style%20of%20this%20wiki.textile +30 -0
  96. data/templates/rails/content/Known%20bugs.textile +8 -0
  97. data/templates/rails/content/List%20of%20changes.textile +34 -0
  98. data/templates/rails/content/Picture%20of%20a%20pair%20of%20soks.textile +1 -0
  99. data/templates/rails/content/Pointers%20on%20adjusting%20the%20settings.textile +62 -0
  100. data/templates/rails/content/Pointers%20on%20how%20to%20use%20this%20wiki.textile +27 -0
  101. data/templates/rails/content/Recent%20Blog%20Entries.textile +3 -0
  102. data/templates/rails/content/Recent%20Changes%20to%20This%20Site.textile +48 -0
  103. data/templates/rails/content/Site%20Index.textile +16 -0
  104. data/templates/rails/content/Soks%20Licence.textile +64 -0
  105. data/templates/rails/content/home%20page.textile +23 -0
  106. data/templates/rails/start.rb +85 -0
  107. data/templates/rails/version.txt +1 -0
  108. data/templates/rails/views/Page_content.rhtml +1 -0
  109. data/templates/rails/views/Page_edit.rhtml +61 -0
  110. data/templates/rails/views/Page_meta.rhtml +38 -0
  111. data/templates/rails/views/Page_print.rhtml +6 -0
  112. data/templates/rails/views/Page_revisions.rhtml +19 -0
  113. data/templates/rails/views/Page_rss.rhtml +55 -0
  114. data/templates/rails/views/Page_search_results.rhtml +19 -0
  115. data/templates/rails/views/Page_view.rhtml +3 -0
  116. data/templates/rails/views/UploadPage_edit.rhtml +38 -0
  117. data/templates/rails/views/frame.rhtml +60 -0
  118. data/templates/rails/views/messages.yaml +6 -0
  119. metadata +122 -28
  120. data/template/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +0 -5
  121. data/template/content/Pointers%20on%20adjusting%20the%20settings.textile +0 -39
  122. data/template/content/Pointers%20on%20how%20to%20use%20this%20wiki.textile +0 -21
  123. data/template/content/Recent%20Changes%20to%20This%20Site.textile +0 -203
  124. data/template/start.rb +0 -74
  125. data/template/views/AttachmentPage_edit.rhtml +0 -36
  126. data/template/views/ImagePage_edit.rhtml +0 -36
  127. data/template/views/Page_edit.rhtml +0 -34
  128. data/template/views/Page_print.rhtml +0 -5
  129. data/template/views/Page_revisions.rhtml +0 -18
  130. data/template/views/Page_rss.rhtml +0 -34
  131. data/template/views/Page_view.rhtml +0 -3
  132. data/template/views/frame.rhtml +0 -34
@@ -529,7 +529,9 @@ class RedCloth < String
529
529
  end unless pre
530
530
  end
531
531
 
532
- line.gsub!( /^(?!\t|<\/?div|<\/?pre|<\/?notextile|<\/?code|$| )(.*)/, "\t<p>\\1</p>" ) unless pre
532
+ # line.gsub!( /^(?!\t|<\/?div|<\/?pre|<\/?notextile|<\/?code|$| )(.*)/, "\t<p>\\1</p>" ) unless pre
533
+
534
+ line.gsub!( /^(?!\t|<\/?div|<\/?pre|<\/?notextile|<\/?code| )(.*)/, "\t<p>\\1</p>" ) unless pre
533
535
 
534
536
  line.gsub!( "<br />", "\n" ) if pre
535
537
  pre = false if line =~ /<\/(pre|notextile)>/i
@@ -5,7 +5,23 @@ require 'base64'
5
5
 
6
6
  module WEBrick
7
7
  module HTTPAuth
8
- class NotAuthentication
8
+
9
+ class NoAuthenticationRequired
10
+
11
+ def authenticate(req, res)
12
+ req.user = req.meta_vars["HTTP_X_FORWARDED_FOR"] || req.meta_vars["REMOTE_ADDR"]
13
+ end
14
+ end
15
+
16
+ class NotPermitted
17
+
18
+ def authenticate(req, res)
19
+ raise WEBrick::HTTPStatus::Unauthorized
20
+ end
21
+
22
+ end
23
+
24
+ class AskForUserName
9
25
 
10
26
  include WEBrick::HTTPAuth::Authenticator
11
27
 
@@ -36,7 +52,7 @@ module WEBrick
36
52
  end
37
53
  end
38
54
 
39
- class OnePasswordAuthentication
55
+ class SiteWidePassword
40
56
  include Authenticator
41
57
 
42
58
  AuthScheme = "Basic"
data/lib/soks-helpers.rb CHANGED
@@ -3,8 +3,8 @@ require 'net/smtp'
3
3
 
4
4
  class AutomaticUpdateCrossLinks
5
5
 
6
- def initialize( wiki )
7
- @wiki = wiki
6
+ def initialize( wiki, view, banned_titles = [] )
7
+ @wiki, @view, @banned_titles = wiki, view, banned_titles
8
8
  @wiki.watch_for( :page_created ) { |event, page| new_page( page ) }
9
9
  @wiki.watch_for( :page_deleted ) { |event, page| delete_page( page ) }
10
10
  @wiki.watch_for( :page_revised ) { |event, page| page_revised( page ) }
@@ -12,208 +12,199 @@ class AutomaticUpdateCrossLinks
12
12
  end
13
13
 
14
14
  def new_page( page )
15
- @wiki.rollingmatch[ page.name ] = page
15
+ return if title_banned? page.name
16
+ @view.rollingmatch[ page.name ] = page
16
17
  titleregex = Regexp.new( page.name, Regexp::IGNORECASE )
17
18
  @wiki.each { |name, linkedpage |
18
- unless name[0,10] == 'Site Index'
19
- @wiki.refresh_redcloth( linkedpage ) if linkedpage.textile =~ titleregex
20
- end
19
+ @view.refresh_redcloth( linkedpage ) if linkedpage.textile =~ titleregex
21
20
  }
22
21
  end
23
22
 
24
23
  def delete_page( page )
25
- @wiki.rollingmatch.delete( page.name )
26
- page.links_to.each { |linkedpage| @wiki.refresh_redcloth( linkedpage ) }
24
+ @view.rollingmatch.delete( page.name )
25
+ page.links_to.each { |linkedpage| @view.refresh_redcloth( linkedpage ) }
27
26
  end
28
27
 
29
28
  def page_revised( page )
30
29
  page.inserted_into.each { |including_page|
31
- @wiki.refresh_redcloth( including_page )
30
+ @view.refresh_redcloth( including_page )
32
31
  }
33
32
  end
34
33
 
35
34
  def update_all_pages
36
- @wiki.each { |pagename, page| @wiki.rollingmatch[ page.name ] = page }
37
- @wiki.each { |pagename, page| @wiki.refresh_redcloth( page ) }
38
- end
39
- end
40
-
41
- class AutomaticRecentChanges
42
-
43
- IGNORED_AUTHORS = /^Automatic/
44
-
45
- def initialize( wiki, lines = 200, pagename = "Recent Changes to This Site", author = "AutomaticRecentChanges" )
46
- @wiki, @lines, @pagename, @author = wiki, lines, pagename, author
47
- @wiki.watch_for( :page_revised ) { |event, page, revision| revised( page, revision ) }
48
- end
49
-
50
- def revised( page, revision )
51
- unless ( revision.author =~ IGNORED_AUTHORS )
52
- add_recent_change( page, revision )
53
- end
54
- end
55
-
56
- def add_recent_change( page, revision )
57
- changes_content = "On #{revision.created_at.strftime('%Y %b %d')}, #{revision.author} made these changes to [[#{page}]]:\n"
58
- revision.changes.each do |change_group| change_group.each do |change|
59
- next if change[2] == ""
60
- changes_content << case change[0]
61
- # Note, +/- reversed because diffs stored as diff from CURRENT version
62
- when "-" ; "| #{change[1]} | -<notextile>#{change[2]}</notextile>- |\n"
63
- when "+" ; "| #{change[1]} | <notextile>#{change[2]}</notextile> |\n"
64
- end
65
- end end
66
- changes_content << "\n"
67
- changes_content << @wiki.page( @pagename ).content.first_lines( @lines ) unless @wiki.page( @pagename ).empty?
68
- @wiki.revise( @pagename , changes_content, @author)
69
- end
70
- end
71
-
72
- class AutomaticOnePageIndex
73
-
74
- def initialize( wiki, pagename = "Site Index", author = "AutomaticIndex" )
75
- @wiki, @pagename, @author = wiki, pagename, author
76
- @wiki.watch_for( :page_created, :page_deleted ) { update_index }
77
- update_index
78
- end
79
-
80
- def update_index
81
- index = @wiki.sort_by{ |name, page| page.name_for_index.capitalize }.map{ |name, page| "* [[ #{page} ]]\n" }
82
- @wiki.revise( @pagename, "h1. Index\n\n#{index}", @author )
83
- end
84
- end
85
-
86
- class AutomaticMultiPageIndex < AutomaticOnePageIndex
87
-
88
- def update_index
89
- buckets = separate_pages_by_first_character
90
- link_bar = link_bar_from_buckets( buckets )
91
- buckets.each do |firstcharacter, pages|
92
- index = pages.sort_by{ |page| page.name_for_index.capitalize }.map{ |page| "* [[ #{page} ]]\n" }
93
- @wiki.revise( "#{@pagename} #{firstcharacter}", "h1. Site Index #{firstcharacter}\n\n#{link_bar}\n\n#{index}", @author )
94
- end
95
- @wiki.revise( @pagename, "h1. Site Index\n\n#{link_bar}", @author )
96
- end
97
-
98
- def separate_pages_by_first_character
99
- buckets = Hash.new
100
- @wiki.each do |name, page|
101
- ( buckets[ page.name_for_index[0,1].upcase ] ||= [] ) << page
102
- end
103
- buckets
104
- end
105
-
106
- def link_bar_from_buckets( buckets )
107
- buckets.keys.sort.map { |letter| "[[ #{letter} : #{@pagename} #{letter} ]]\n" }.join(' ')
108
- end
109
- end
110
-
111
- class FiniteUniqueList
112
- include Enumerable
113
-
114
- attr_accessor :max_size
115
-
116
- def initialize( max_size = nil )
117
- @max_size = max_size
118
- @list = Array.new
119
- end
120
-
121
- def add( item )
122
- remove( item )
123
- @list << item
124
- remove_excess_items
125
- end
126
-
127
- def remove( item )
128
- @list.delete( item )
35
+ @wiki.each { |pagename, page| @view.rollingmatch[ page.name ] = page unless title_banned?( page.name )}
36
+ @wiki.each { |pagename, page| @view.refresh_redcloth( page ) }
129
37
  end
130
38
 
131
- def each
132
- @list.reverse_each { |item| yield item }
39
+ def title_banned?( title )
40
+ @banned_titles.include? title
133
41
  end
134
42
 
135
- def empty?; @list.empty? end
136
-
137
- private
138
-
139
- def remove_excess_items
140
- if @max_size
141
- while @list.size > @max_size
142
- @list.shift
143
- end
144
- end
145
- end
146
43
  end
147
44
 
148
45
  class AutomaticSummary
149
46
 
150
47
  DEFAULT_SETTINGS = {
151
- :regexp_for_pages => /.*/,
48
+ :regexp_for_title => /.*/, # These three regexps act as an AND
49
+ :regexp_for_author => nil,
50
+ :regexp_for_content => nil,
152
51
  :max_pages_to_show => nil,
153
52
  :pagename => 'Summary',
154
53
  :author => 'AutomaticSummary',
155
- :lines_to_include => nil,
54
+ :lines_to_include => nil, # Or pass a block
156
55
  :only_new_pages => false,
56
+ :sort_pages_by => :created_on, # Could be :revised_on or :score or :name or :name_for_index, or :author
57
+ :reverse_sort => false,
58
+ :include_metadata => false, # Includes author and time in summary
59
+ :summarise_revisions => false, # If true, then can contain several revisions for same page
60
+ :remove_deleted_pages => true, # If false will keep references to deleted pages
157
61
  }
158
62
 
159
63
  attr_reader :settings, :pages_in_summary
160
64
 
161
- def initialize( wiki, settings = {} )
162
- @wiki = wiki
163
- @settings = DEFAULT_SETTINGS.merge( settings )
164
- @pages_in_summary = FiniteUniqueList.new( @settings[:max_pages_to_show] )
165
- scan_for_pages_to_summarise
65
+ def initialize( wiki, settings = {}, &renderer )
66
+ @wiki, @settings, @renderer = wiki, DEFAULT_SETTINGS.merge( settings ), renderer
67
+ setup_list
68
+ scan_for_pages_to_summarise_in wiki
166
69
  render_summary
167
- @wiki.watch_for( @settings[:only_new_pages] ? :page_created : :page_revised ) { |event, page| check_whether_to_add_page( page ) }
168
- @wiki.watch_for( :page_deleted ) { |event, page| check_whether_to_remove_page( page ) }
70
+ start_watching_wiki wiki
169
71
  end
170
72
 
171
- def check_whether_to_add_page( page )
73
+ def check_whether_to_add_page( page, revision )
172
74
  return if page.name == @settings[:pagename]
173
- if page.name=~ @settings[:regexp_for_pages]
174
- @pages_in_summary.add( page )
75
+ if summarise? page
76
+ @pages_in_summary.add( @settings[:summarise_revisions] ? revision : page )
175
77
  render_summary
176
78
  end
177
79
  end
178
80
 
179
- def check_whether_to_remove_page( page )
180
- render_summary if @pages_in_summary.remove( page )
81
+ def check_whether_to_remove_page( page, revision )
82
+ return unless @settings[:remove_deleted_pages]
83
+ render_summary if @pages_in_summary.remove( @settings[:summarise_revisions] ? revision : page )
181
84
  end
182
85
 
183
- def scan_for_pages_to_summarise
184
- @wiki.select do |name,page|
185
- name=~ @settings[:regexp_for_pages]
186
- end.sort_by do |name, page|
187
- (@settings[:only_new_pages] ? page.revision[0] : page).created_at
188
- end.each do |name, page|
189
- @pages_in_summary.add page
86
+ private
87
+
88
+ def summarise?( page )
89
+ return false if @settings[:regexp_for_title] && page.name !~ @settings[:regexp_for_title]
90
+ return false if @settings[:regexp_for_author] && page.author !~ @settings[:regexp_for_author]
91
+ return false if @settings[:regexp_for_content] && page.content !~ @settings[:regexp_for_content]
92
+ return true
93
+ end
94
+
95
+ def scan_for_pages_to_summarise_in( wiki )
96
+ wiki.each( @settings[:remove_deleted_pages] ) do |name,page|
97
+ next if page.name == @settings[:pagename]
98
+ next unless summarise? page
99
+ if @settings[:summarise_revisions]
100
+ page.revisions.each { |revision| @pages_in_summary.add revision }
101
+ else
102
+ @pages_in_summary.add page
103
+ end
190
104
  end
191
105
  end
192
106
 
193
107
  def render_summary
108
+ if @wiki.exists? @settings[:pagename]
109
+ old_page = @wiki.page( @settings[:pagename] )
110
+ if old_page.textile =~ /(.*?<automaticsummary>).*?(<\/automaticsummary>.*)/mi
111
+ content, tail = $1, $2
112
+ end
113
+ end
114
+ 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>"
115
+ tail ||= "</automaticsummary>"
116
+ content << "\n\n"
194
117
  if @pages_in_summary.empty?
195
- @wiki.revise( @settings[:pagename], "No pages found to summarise" , @settings[:author] )
118
+ content << "No pages found to summarise"
119
+ elsif @renderer
120
+ @pages_in_summary.each { |page| content << @renderer.call(page) }
121
+ elsif @settings[:lines_to_include]
122
+ @pages_in_summary.each { |page| content << render_page(page) }
196
123
  else
197
- content = ""
198
- @pages_in_summary.each do |page|
199
- content << "<div class='subpage'>\n\n"
200
- content << render_page( page )
201
- content << "\n\np(more). [[(more) : #{page.name}]]\n\n"
202
- content << "</div>\n"
203
- end
204
- @wiki.revise( @settings[:pagename], content , @settings[:author] )
124
+ @pages_in_summary.each { |page| content << render_link_to(page) }
205
125
  end
126
+ content << "\n\n"
127
+ content << tail
128
+ @wiki.revise( @settings[:pagename], content , @settings[:author] )
206
129
  end
207
130
 
208
131
  def render_page( page )
209
- if @settings[:lines_to_include]
210
- page.textile.first_lines( @settings[:lines_to_include] )
211
- else
212
- page.textile
213
- end
132
+ "<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"
133
+ end
134
+
135
+ def render_link_to( page )
136
+ "* #{page.name} #{ @settings[:include_metadata] ? render_meta_data( page ) : "" }\n"
137
+ end
138
+
139
+ def render_meta_data( page )
140
+ "revised on #{page.revised_on.strftime('%Y %b %d %H:%M')} by #{page.author}"
141
+ end
142
+
143
+ def setup_list
144
+ @pages_in_summary = FiniteUniqueList.new( @settings[:max_pages_to_show],
145
+ @settings[:reverse_sort],
146
+ @settings[:sort_pages_by] )
214
147
  end
148
+
149
+ def start_watching_wiki( wiki )
150
+ wiki.watch_for( @settings[:only_new_pages] ? :page_created : :page_revised ) { |event, page, revision| check_whether_to_add_page( page, revision ) }
151
+ wiki.watch_for( :page_deleted ) { |event, page, revision| check_whether_to_remove_page( page, revision ) } if @settings[:remove_deleted_pages]
152
+ end
153
+
215
154
  end
216
155
 
156
+ class AutomaticRecentChanges
157
+
158
+ def initialize( wiki, changes = 200, pagename = "Recent Changes to This Site", author = "AutomaticRecentChanges" )
159
+ AutomaticSummary.new( wiki, { :pagename => pagename,
160
+ :author => author,
161
+ :only_new_pages => false,
162
+ :sort_pages_by => :revised_on,
163
+ :include_metadata => true,
164
+ :summarise_revisions => true,
165
+ :reverse_sort => true,
166
+ :remove_deleted_pages => false,
167
+ } )
168
+ end
169
+ end
170
+
171
+ class AutomaticOnePageIndex
172
+
173
+ def initialize( wiki, pagename = "Site Index", author = "AutomaticIndex" )
174
+ AutomaticSummary.new( wiki, { :pagename => pagename,
175
+ :author => author,
176
+ :only_new_pages => true,
177
+ :sort_pages_by => :name_for_index,
178
+ } )
179
+ end
180
+
181
+ end
182
+
183
+ class AutomaticMultiPageIndex
184
+
185
+ def initialize( wiki, pageroot = "Site Index", author = "AutomaticIndex" )
186
+ content = "h1. #{pageroot}\n\n"
187
+ ('A'..'Z').each do |letter|
188
+ AutomaticSummary.new( wiki, { :regexp_for_title => /^#{letter}.*/i,
189
+ :pagename => "#{pageroot} #{letter}",
190
+ :author => author,
191
+ :only_new_pages => true,
192
+ :sort_pages_by => :name_for_index,
193
+ } )
194
+ content << "* #{pageroot} #{letter}\n"
195
+ end
196
+ AutomaticSummary.new( wiki, { :regexp_for_title => /^[^A-Za-z].*/,
197
+ :pagename => "#{pageroot} Other",
198
+ :author => author,
199
+ :only_new_pages => true,
200
+ :sort_pages_by => :name_for_index,
201
+ } )
202
+ content << "* #{pageroot} Other\n"
203
+ wiki.revise( pageroot, content, author )
204
+ end
205
+
206
+ end
207
+
217
208
  class AutomaticCalendar
218
209
 
219
210
  attr_reader :month_pagename, :day_pagename
@@ -240,12 +231,13 @@ class AutomaticCalendar
240
231
  1.upto( 31 ) do |day_no|
241
232
  day = time_for( month, day_no )
242
233
  break if day.month > month
243
- content << "| [[ #{day_no} : #{day_pagename( day )} ]] "
234
+ content << "| [[ #{day_no} => #{day_pagename( day )} ]] "
244
235
  content << "|\n" if day.wday == 6
245
236
  end
246
237
  day.wday.upto( 5 ) { content << "| . " }
247
238
  content << "|\n"
248
- content << "\n\n< #{month_pagename( month-1 )} #{month_pagename( month+1 )} >\n"
239
+ content << "\n\n< #{month_pagename( month-1 )} #{month_pagename( month+1 )} >\n"
240
+ content << "</div>"
249
241
  end
250
242
 
251
243
  def time_for( month, day = 1 )
@@ -290,10 +282,10 @@ class AutomaticUpcomingEvents
290
282
  content = "<div class='upcomingevents'>\n"
291
283
  Time.now.day.upto( Time.now.day+7 ) do |day|
292
284
  time = @calendar.time_for( Time.now.month, day )
293
- content << "| [[ #{relative_day( time ) } : #{@calendar.day_pagename( time )} ]] |"
285
+ content << "| [[ #{relative_day( time ) } => #{@calendar.day_pagename( time )} ]] |"
294
286
  content << (@wiki.exists?( @calendar.day_pagename(time) ) ? render_event( @calendar.day_pagename( time ) ) : "&nbsp; |\n")
295
287
  end
296
- content << "\n\np(more). [[(more) : #{@calendar.month_pagename}]]\n\n"
288
+ content << "\n\np(more). [[(more) => #{@calendar.month_pagename}]]\n\n"
297
289
  content << "</div>\n"
298
290
  @wiki.revise( "Upcoming Events", content , "AutomaticCalendar" )
299
291
  end
@@ -313,9 +305,67 @@ class AutomaticUpcomingEvents
313
305
  page = @wiki.page( name )
314
306
  headings = page.textile.select { |line| line =~ /^h\d\./ }
315
307
  headings = headings.map { |heading| heading.to_s[4..-1].strip }
316
- headings = [ page.textile[/.*?\n/] ] if headings.empty?
317
- content = "[[ #{headings.shift} : #{page.name} ]] |\n"
318
- headings.each { |heading| content << "| &nbsp; | [[ #{heading} : #{page.name} ]] |\n" }
308
+ headings = [ page.textile.first_lines(1) ] if headings.empty?
309
+ content = " [[ #{headings.shift} => #{page.name} ]] |\n"
310
+ headings.each { |heading| content << "| &nbsp; | [[ #{heading} => #{page.name} ]] |\n" }
319
311
  content
320
312
  end
321
313
  end
314
+
315
+ class AutomaticAuthorIndex
316
+
317
+ def initialize( wiki, create_author_pages = true, author_include_regexp = /.*/, author_exclude_regexp = /^Automatic.*/, pagename = "authors", author = "AutomaticAuthorIndexer", author_page_tail = "s pages" )
318
+ @wiki, @create_author_pages, @author_include_regexp, @author_exclude_regexp, @pagename, @author, @author_page_tail = wiki, create_author_pages, author_include_regexp, author_exclude_regexp, pagename, author, author_page_tail
319
+ @authors = []
320
+ find_all_authors( wiki )
321
+ @wiki.watch_for( :page_revised ) { |event, page, revision|
322
+ $stderr.puts "Got a page revised message in AutomaticAuthorIndex"
323
+ add_author( revision ) }
324
+ end
325
+
326
+ def add_author( revision )
327
+ return if @authors.include? revision.author
328
+ return unless revision.author =~ @author_include_regexp
329
+ return unless revision.author !~ @author_exclude_regexp
330
+ @authors << revision.author
331
+ @authors.sort!
332
+ create_author_page_for(revision.author) if @create_author_pages
333
+ render_author_index
334
+ end
335
+
336
+ def find_all_authors( wiki )
337
+ wiki.each do |name, page|
338
+ page.revisions.each do |revision|
339
+ add_author( revision )
340
+ end
341
+ end
342
+ end
343
+
344
+ def render_author_index
345
+ content = "h1. Index of Authors\n\n"
346
+ @authors.each do |author|
347
+ content << "* #{author}"
348
+ if @create_author_pages
349
+ content << " #{author}#{@author_page_tail}"
350
+ end
351
+ content << "\n"
352
+ end
353
+ @wiki.revise( @pagename, content, @author )
354
+ end
355
+
356
+
357
+ def create_author_page_for( author )
358
+ AutomaticSummary.new( @wiki, { :pagename => "#{author}#{@author_page_tail}" ,
359
+ :regexp_for_author => /#{author}/,
360
+ :author => @author,
361
+ :only_new_pages => false,
362
+ :sort_pages_by => :revised_on,
363
+ :include_metadata => true,
364
+ :summarise_revisions => true,
365
+ :reverse_sort => true,
366
+ :remove_deleted_pages => false,
367
+ } )
368
+ end
369
+
370
+ end
371
+