Soks 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +5 -4
- data/bin/soks-create-wiki.rb +153 -19
- data/contrib/easyprompt.rb +58 -0
- data/contrib/easyprompt_licence.txt +504 -0
- data/contrib/redcloth-2.0.11.rb +3 -1
- data/lib/authenticators.rb +18 -2
- data/lib/soks-helpers.rb +207 -157
- data/lib/soks-model.rb +131 -114
- data/lib/soks-servlet.rb +54 -35
- data/lib/soks-storage.rb +134 -0
- data/lib/soks-upgrade-0.0.2.rb +70 -0
- data/lib/soks-utils.rb +129 -19
- data/lib/soks-view.rb +136 -62
- data/lib/soks.rb +3 -1
- data/{template → templates/default}/attachment/logo.png +0 -0
- data/templates/default/attachment/logo.tiff +0 -0
- data/templates/default/attachment/newpage.js +41 -0
- data/templates/default/attachment/print_stylesheet.css +7 -0
- data/templates/default/attachment/rss.png +0 -0
- data/{template → templates/default}/attachment/stylesheet.css +44 -17
- data/templates/default/banned_titles.txt +31 -0
- data/templates/default/content/Bug%3A%20In%20a%20list%20of%20links%2C%20the%20last%20link%20is%20sometimes%20not%20linked.textile +10 -0
- data/templates/default/content/Bug%3A%20Symbols%20are%20not%20always%20correctly%20rendered%20in%20html.textile +3 -0
- data/templates/default/content/Bug%3A%20Uploads%20are%20not%20password%20protected.textile +3 -0
- data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +62 -0
- data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +30 -0
- data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +60 -0
- data/{template → templates/default}/content/How%20to%20hack%20soks.textile +3 -2
- data/{template → templates/default}/content/How%20to%20import%20a%20site%20from%20instiki.textile +1 -1
- data/templates/default/content/How%20to%20use%20this%20wiki.textile +27 -0
- data/templates/default/content/List%20of%20changes.textile +35 -0
- data/{template → templates/default}/content/Picture%20of%20a%20pair%20of%20soks.textile +0 -0
- data/{template → templates/default}/content/Soks%20Licence.textile +0 -0
- data/templates/default/content/home%20page.textile +17 -0
- data/templates/default/start.rb +94 -0
- data/templates/default/version.txt +1 -0
- data/{template → templates/default}/views/Page_content.rhtml +0 -0
- data/templates/default/views/Page_edit.rhtml +61 -0
- data/templates/default/views/Page_meta.rhtml +40 -0
- data/templates/default/views/Page_print.rhtml +6 -0
- data/templates/default/views/Page_revisions.rhtml +19 -0
- data/templates/default/views/Page_rss.rhtml +55 -0
- data/{template → templates/default}/views/Page_search_results.rhtml +1 -1
- data/templates/default/views/Page_view.rhtml +4 -0
- data/templates/default/views/UploadPage_edit.rhtml +38 -0
- data/templates/default/views/frame.rhtml +41 -0
- data/templates/default/views/messages.yaml +6 -0
- data/templates/instiki/attachment/header_backdrop.png +0 -0
- data/templates/instiki/attachment/instiki_style_sheet.css +199 -0
- data/templates/instiki/attachment/logo.tiff +0 -0
- data/templates/instiki/attachment/logotext.png +0 -0
- data/templates/instiki/attachment/newpage.js +41 -0
- data/templates/instiki/attachment/rss.png +0 -0
- data/templates/instiki/banned_titles.txt +31 -0
- data/templates/instiki/content/AutomaticSummary.textile +24 -0
- data/templates/instiki/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +60 -0
- data/templates/instiki/content/How%20to%20hack%20soks.textile +61 -0
- data/templates/instiki/content/How%20to%20import%20a%20site%20from%20instiki.textile +13 -0
- data/{template → templates/instiki}/content/Improving%20the%20style%20of%20this%20wiki.textile +2 -2
- data/templates/instiki/content/Known%20bugs.textile +8 -0
- data/templates/instiki/content/List%20of%20changes.textile +34 -0
- data/templates/instiki/content/Picture%20of%20a%20pair%20of%20soks.textile +1 -0
- data/templates/instiki/content/Pointers%20on%20adjusting%20the%20settings.textile +62 -0
- data/templates/instiki/content/Pointers%20on%20how%20to%20use%20this%20wiki.textile +27 -0
- data/templates/instiki/content/Recent%20Blog%20Entries.textile +3 -0
- data/templates/instiki/content/Recent%20Changes%20to%20This%20Site.textile +48 -0
- data/templates/instiki/content/Site%20Index.textile +16 -0
- data/templates/instiki/content/Soks%20Licence.textile +64 -0
- data/{template → templates/instiki}/content/home%20page.textile +9 -4
- data/templates/instiki/start.rb +85 -0
- data/templates/instiki/version.txt +1 -0
- data/templates/instiki/views/Page_content.rhtml +1 -0
- data/templates/instiki/views/Page_edit.rhtml +8 -0
- data/templates/instiki/views/Page_meta.rhtml +34 -0
- data/templates/instiki/views/Page_print.rhtml +6 -0
- data/templates/instiki/views/Page_revisions.rhtml +17 -0
- data/templates/instiki/views/Page_rss.rhtml +55 -0
- data/templates/instiki/views/Page_search_results.rhtml +18 -0
- data/templates/instiki/views/Page_view.rhtml +2 -0
- data/templates/instiki/views/UploadPage_edit.rhtml +16 -0
- data/templates/instiki/views/frame.rhtml +90 -0
- data/templates/instiki/views/messages.yaml +6 -0
- data/templates/rails/attachment/2colheader.css +77 -0
- data/templates/rails/attachment/basics.css +98 -0
- data/templates/rails/attachment/header_backdrop.png +0 -0
- data/templates/rails/attachment/logo.tiff +0 -0
- data/templates/rails/attachment/logotext.png +0 -0
- data/templates/rails/attachment/newpage.js +41 -0
- data/templates/rails/attachment/rss.png +0 -0
- data/templates/rails/banned_titles.txt +31 -0
- data/templates/rails/content/AutomaticSummary.textile +24 -0
- data/templates/rails/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +60 -0
- data/templates/rails/content/How%20to%20hack%20soks.textile +61 -0
- data/templates/rails/content/How%20to%20import%20a%20site%20from%20instiki.textile +13 -0
- data/templates/rails/content/Improving%20the%20style%20of%20this%20wiki.textile +30 -0
- data/templates/rails/content/Known%20bugs.textile +8 -0
- data/templates/rails/content/List%20of%20changes.textile +34 -0
- data/templates/rails/content/Picture%20of%20a%20pair%20of%20soks.textile +1 -0
- data/templates/rails/content/Pointers%20on%20adjusting%20the%20settings.textile +62 -0
- data/templates/rails/content/Pointers%20on%20how%20to%20use%20this%20wiki.textile +27 -0
- data/templates/rails/content/Recent%20Blog%20Entries.textile +3 -0
- data/templates/rails/content/Recent%20Changes%20to%20This%20Site.textile +48 -0
- data/templates/rails/content/Site%20Index.textile +16 -0
- data/templates/rails/content/Soks%20Licence.textile +64 -0
- data/templates/rails/content/home%20page.textile +23 -0
- data/templates/rails/start.rb +85 -0
- data/templates/rails/version.txt +1 -0
- data/templates/rails/views/Page_content.rhtml +1 -0
- data/templates/rails/views/Page_edit.rhtml +61 -0
- data/templates/rails/views/Page_meta.rhtml +38 -0
- data/templates/rails/views/Page_print.rhtml +6 -0
- data/templates/rails/views/Page_revisions.rhtml +19 -0
- data/templates/rails/views/Page_rss.rhtml +55 -0
- data/templates/rails/views/Page_search_results.rhtml +19 -0
- data/templates/rails/views/Page_view.rhtml +3 -0
- data/templates/rails/views/UploadPage_edit.rhtml +38 -0
- data/templates/rails/views/frame.rhtml +60 -0
- data/templates/rails/views/messages.yaml +6 -0
- metadata +122 -28
- data/template/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +0 -5
- data/template/content/Pointers%20on%20adjusting%20the%20settings.textile +0 -39
- data/template/content/Pointers%20on%20how%20to%20use%20this%20wiki.textile +0 -21
- data/template/content/Recent%20Changes%20to%20This%20Site.textile +0 -203
- data/template/start.rb +0 -74
- data/template/views/AttachmentPage_edit.rhtml +0 -36
- data/template/views/ImagePage_edit.rhtml +0 -36
- data/template/views/Page_edit.rhtml +0 -34
- data/template/views/Page_print.rhtml +0 -5
- data/template/views/Page_revisions.rhtml +0 -18
- data/template/views/Page_rss.rhtml +0 -34
- data/template/views/Page_view.rhtml +0 -3
- data/template/views/frame.rhtml +0 -34
data/contrib/redcloth-2.0.11.rb
CHANGED
@@ -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
|
data/lib/authenticators.rb
CHANGED
@@ -5,7 +5,23 @@ require 'base64'
|
|
5
5
|
|
6
6
|
module WEBrick
|
7
7
|
module HTTPAuth
|
8
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
@
|
26
|
-
page.links_to.each { |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
|
-
@
|
30
|
+
@view.refresh_redcloth( including_page )
|
32
31
|
}
|
33
32
|
end
|
34
33
|
|
35
34
|
def update_all_pages
|
36
|
-
@wiki.each { |pagename, page| @
|
37
|
-
@wiki.each { |pagename, 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
|
132
|
-
@
|
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
|
-
|
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
|
-
|
164
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
-
|
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
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
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}
|
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 ) }
|
285
|
+
content << "| [[ #{relative_day( time ) } => #{@calendar.day_pagename( time )} ]] |"
|
294
286
|
content << (@wiki.exists?( @calendar.day_pagename(time) ) ? render_event( @calendar.day_pagename( time ) ) : " |\n")
|
295
287
|
end
|
296
|
-
content << "\n\np(more). [[(more)
|
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
|
317
|
-
content = "[[ #{headings.shift}
|
318
|
-
headings.each { |heading| content << "| | [[ #{heading}
|
308
|
+
headings = [ page.textile.first_lines(1) ] if headings.empty?
|
309
|
+
content = " [[ #{headings.shift} => #{page.name} ]] |\n"
|
310
|
+
headings.each { |heading| content << "| | [[ #{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
|
+
|