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.
- 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
|
+
|