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.
- data/README.txt +4 -0
- data/lib/helpers/default-helpers.rb +94 -56
- data/lib/helpers/mail2wiki-helper.rb +8 -6
- data/lib/soks-servlet.rb +19 -16
- data/lib/soks-storage.rb +6 -7
- data/lib/soks-utils.rb +26 -0
- data/lib/soks-view.rb +4 -4
- data/lib/soks.rb +2 -1
- data/templates/default/attachment/newpage.js +2 -2
- data/templates/default/attachment/stylesheet.css +14 -3
- data/templates/default/content/A%20page%20with%20an%20umlaut%20%F6%20in%20its%20title.textile +1 -0
- data/templates/default/content/All%20News.textile +18 -1
- data/templates/default/content/Bil%20Kleb.textile +1 -0
- data/templates/default/content/Bil.textile +1 -0
- data/templates/default/content/Bill%20Wood.textile +3 -0
- data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +1 -0
- data/templates/default/content/Bug%3A%20Type%20a%20title%20here.textile +31 -0
- data/templates/default/content/How%20to%20use%20the%20keyboard%20shortcuts.textile +4 -2
- data/templates/default/content/Latest%20News.textile +19 -2
- data/templates/default/content/List%20of%20changes.textile +43 -0
- data/templates/default/content/New%20Recent%20Changes%20class.textile +10 -0
- data/templates/default/content/News%3A%20Version%200%2E0%2E6%20Released.textile +13 -0
- data/templates/default/content/Planned%20Features.textile +9 -8
- data/templates/default/content/README.textile +4 -0
- data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +282 -205
- data/templates/default/content/Skorgu.textile +3 -0
- data/templates/default/content/ctrl%2Dn.textile +1 -1
- data/templates/default/content/sandbox.textile +20 -0
- data/templates/default/start.rb +15 -5
- data/templates/default/version.txt +1 -1
- data/templates/default/views/Page_edit.rhtml +6 -3
- data/templates/default/views/frame.rhtml +3 -2
- data/test/test_soks-storage.rb +69 -0
- data/test/test_soks-utils.rb +84 -0
- data/test/test_soks-view.rb +43 -0
- metadata +14 -11
- data/templates/default/content/Attached%20ruby%20logo.textile +0 -1
- data/templates/default/content/Attached%20test%20thing.textile +0 -1
- data/templates/default/content/Known%20bugs.textile +0 -18
- data/templates/default/content/Picture%20of%20Type%20a%20title%20here.textile +0 -1
- data/templates/default/content/Picture%20of%20a%20logo%20for%20the%20ruby%20language.textile +0 -1
- data/templates/default/content/Picture%20of%20powered%20by%20ruby%20logo.textile +0 -1
- data/templates/default/content/Recent%20News.textile +0 -9
- 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
|
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
|
-
|
77
|
+
start_watching wiki
|
74
78
|
end
|
75
79
|
|
76
80
|
def check_whether_to_add_page( page, revision )
|
77
|
-
return
|
78
|
-
if
|
79
|
-
|
80
|
-
|
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
|
-
|
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
|
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
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
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
|
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
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
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
|
-
|
180
|
-
|
181
|
-
|
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
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
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.
|
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
|
-
|
144
|
-
|
145
|
+
:ServerType=> $SETTINGS[:server_type]
|
146
|
+
} )
|
145
147
|
|
146
148
|
server.mount("/", WikiServlet, view, $SETTINGS )
|
147
149
|
|
148
150
|
trap("INT") {
|
149
|
-
$
|
151
|
+
$LOG.warn "Trying to shutdown gracefully"
|
150
152
|
server.shutdown
|
151
153
|
wiki.shutdown
|
152
|
-
$
|
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 = '
|
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
|
-
$
|
67
|
+
$LOG.error "Error loading revisions with #{$!.to_s} in file #{page.name}"
|
68
68
|
end
|
69
|
-
revisions.each_with_index { |r,i| $
|
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
|
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
|
-
$
|
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 =
|
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
|
-
|
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
|
-
$
|
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
|
-
$
|
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
|
-
|
203
|
-
|
204
|
-
|
212
|
+
|
213
|
+
.recentchanges li, .recentchanges ul {
|
214
|
+
list-style-type: none;
|
215
|
+
padding-left: 5px;
|
205
216
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
Test whether this works.
|
@@ -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
|
-
|
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 @@
|
|
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
|
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
|