instiki 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/CHANGELOG +174 -165
  2. data/README +68 -68
  3. data/app/controllers/admin_controller.rb +94 -94
  4. data/app/controllers/application.rb +135 -131
  5. data/app/controllers/file_controller.rb +129 -129
  6. data/app/controllers/wiki_controller.rb +354 -354
  7. data/app/helpers/application_helper.rb +68 -68
  8. data/app/models/author.rb +3 -3
  9. data/app/models/chunks/category.rb +33 -33
  10. data/app/models/chunks/chunk.rb +86 -86
  11. data/app/models/chunks/engines.rb +61 -54
  12. data/app/models/chunks/include.rb +41 -41
  13. data/app/models/chunks/literal.rb +31 -31
  14. data/app/models/chunks/nowiki.rb +28 -28
  15. data/app/models/chunks/test.rb +18 -18
  16. data/app/models/chunks/uri.rb +182 -182
  17. data/app/models/chunks/wiki.rb +141 -141
  18. data/app/models/file_yard.rb +58 -58
  19. data/app/models/page.rb +112 -112
  20. data/app/models/page_lock.rb +22 -22
  21. data/app/models/page_set.rb +89 -89
  22. data/app/models/revision.rb +123 -123
  23. data/app/models/web.rb +182 -176
  24. data/app/models/wiki_content.rb +207 -207
  25. data/app/models/wiki_service.rb +233 -233
  26. data/app/models/wiki_words.rb +23 -23
  27. data/app/views/admin/create_system.rhtml +83 -83
  28. data/app/views/admin/create_web.rhtml +69 -69
  29. data/app/views/admin/edit_web.rhtml +137 -136
  30. data/app/views/file/file.rhtml +18 -18
  31. data/app/views/file/import.rhtml +22 -22
  32. data/app/views/layouts/default.rhtml +86 -85
  33. data/app/views/markdown_help.rhtml +12 -12
  34. data/app/views/mixed_help.rhtml +6 -6
  35. data/app/views/navigation.rhtml +30 -30
  36. data/app/views/rdoc_help.rhtml +12 -12
  37. data/app/views/textile_help.rhtml +24 -24
  38. data/app/views/wiki/authors.rhtml +11 -11
  39. data/app/views/wiki/edit.rhtml +39 -39
  40. data/app/views/wiki/export.rhtml +12 -12
  41. data/app/views/wiki/feeds.rhtml +14 -14
  42. data/app/views/wiki/list.rhtml +64 -64
  43. data/app/views/wiki/locked.rhtml +23 -23
  44. data/app/views/wiki/login.rhtml +14 -14
  45. data/app/views/wiki/new.rhtml +31 -31
  46. data/app/views/wiki/page.rhtml +115 -115
  47. data/app/views/wiki/print.rhtml +14 -14
  48. data/app/views/wiki/published.rhtml +9 -9
  49. data/app/views/wiki/recently_revised.rhtml +26 -26
  50. data/app/views/wiki/revision.rhtml +103 -103
  51. data/app/views/wiki/rollback.rhtml +36 -36
  52. data/app/views/wiki/rss_feed.rhtml +22 -22
  53. data/app/views/wiki/search.rhtml +38 -38
  54. data/app/views/wiki/tex.rhtml +22 -22
  55. data/app/views/wiki/tex_web.rhtml +34 -34
  56. data/app/views/wiki/web_list.rhtml +18 -18
  57. data/app/views/wiki_words_help.rhtml +9 -9
  58. data/config/environment.rb +82 -82
  59. data/config/environments/development.rb +5 -5
  60. data/config/environments/production.rb +4 -4
  61. data/config/environments/test.rb +17 -17
  62. data/config/routes.rb +18 -18
  63. data/lib/active_record_stub.rb +31 -31
  64. data/lib/bluecloth_tweaked.rb +1127 -0
  65. data/lib/diff.rb +444 -444
  66. data/lib/instiki_errors.rb +14 -14
  67. data/lib/rdocsupport.rb +151 -151
  68. data/lib/redcloth_for_tex.rb +736 -736
  69. data/natives/osx/desktop_launcher/AppDelegate.h +18 -18
  70. data/natives/osx/desktop_launcher/AppDelegate.mm +109 -109
  71. data/natives/osx/desktop_launcher/Credits.html +15 -15
  72. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/classes.nib +12 -12
  73. data/natives/osx/desktop_launcher/English.lproj/MainMenu.nib/info.nib +24 -24
  74. data/natives/osx/desktop_launcher/Info.plist +12 -12
  75. data/natives/osx/desktop_launcher/Instiki.xcode/project.pbxproj +592 -592
  76. data/natives/osx/desktop_launcher/Instiki_Prefix.pch +7 -7
  77. data/natives/osx/desktop_launcher/MakeDMG.sh +9 -9
  78. data/natives/osx/desktop_launcher/main.mm +14 -14
  79. data/natives/osx/desktop_launcher/version.plist +16 -16
  80. data/public/404.html +5 -5
  81. data/public/500.html +5 -5
  82. data/public/dispatch.rb +9 -9
  83. data/public/javascripts/edit_web.js +52 -52
  84. data/public/javascripts/prototype.js +336 -336
  85. data/public/stylesheets/instiki.css +222 -222
  86. data/script/breakpointer +4 -4
  87. data/script/server +93 -93
  88. metadata +4 -3
@@ -1,233 +1,233 @@
1
- require 'open-uri'
2
- require 'yaml'
3
- require 'madeleine'
4
- require 'madeleine/automatic'
5
- require 'madeleine/zmarshal'
6
-
7
- require 'web'
8
- require 'page'
9
- require 'author'
10
- require 'file_yard'
11
- require 'instiki_errors'
12
-
13
- module AbstractWikiService
14
-
15
- attr_reader :webs, :system
16
-
17
- def authenticate(password)
18
- # system['password'] variant is for compatibility with storages from older versions
19
- password == (@system[:password] || @system['password'] || 'instiki')
20
- end
21
-
22
- def create_web(name, address, password = nil)
23
- @webs[address] = Web.new(self, name, address, password) unless @webs[address]
24
- end
25
-
26
- def delete_web(address)
27
- @webs[address] = nil
28
- end
29
-
30
- def file_yard(web)
31
- raise "Web #{@web.name} does not belong to this wiki service" unless @webs.values.include?(web)
32
- # TODO cache FileYards
33
- FileYard.new("#{self.storage_path}/#{web.address}", web.max_upload_size)
34
- end
35
-
36
- def init_wiki_service
37
- @webs = {}
38
- @system = {}
39
- end
40
-
41
- def read_page(web_address, page_name)
42
- ApplicationController.logger.debug "Reading page '#{page_name}' from web '#{web_address}'"
43
- web = @webs[web_address]
44
- if web.nil?
45
- ApplicationController.logger.debug "Web '#{web_address}' not found"
46
- return nil
47
- else
48
- page = web.pages[page_name]
49
- ApplicationController.logger.debug "Page '#{page_name}' #{page.nil? ? 'not' : ''} found"
50
- return page
51
- end
52
- end
53
-
54
- def remove_orphaned_pages(web_address)
55
- @webs[web_address].remove_pages(@webs[web_address].select.orphaned_pages)
56
- end
57
-
58
- def revise_page(web_address, page_name, content, revised_on, author)
59
- page = read_page(web_address, page_name)
60
- page.revise(content, revised_on, author)
61
- page
62
- end
63
-
64
- def rollback_page(web_address, page_name, revision_number, created_at, author_id = nil)
65
- page = read_page(web_address, page_name)
66
- page.rollback(revision_number, created_at, author_id)
67
- page
68
- end
69
-
70
- def setup(password, web_name, web_address)
71
- @system[:password] = password
72
- create_web(web_name, web_address)
73
- end
74
-
75
- def setup?
76
- not (@webs.empty?)
77
- end
78
-
79
- def edit_web(old_address, new_address, name, markup, color, additional_style, safe_mode = false,
80
- password = nil, published = false, brackets_only = false, count_pages = false,
81
- allow_uploads = true, max_upload_size = nil)
82
-
83
- if not @webs.key? old_address
84
- raise Instiki::ValidationError.new("Web with address '#{old_address}' does not exist")
85
- end
86
-
87
- if old_address != new_address
88
- if @webs.key? new_address
89
- raise Instiki::ValidationError.new("There is already a web with address '#{new_address}'")
90
- end
91
- @webs[new_address] = @webs[old_address]
92
- @webs.delete(old_address)
93
- @webs[new_address].address = new_address
94
- end
95
-
96
- web = @webs[new_address]
97
- web.refresh_revisions if settings_changed?(web, markup, safe_mode, brackets_only)
98
-
99
- web.name, web.markup, web.color, web.additional_style, web.safe_mode =
100
- name, markup, color, additional_style, safe_mode
101
-
102
- web.password, web.published, web.brackets_only, web.count_pages =
103
- password, published, brackets_only, count_pages, allow_uploads
104
- web.allow_uploads, web.max_upload_size = allow_uploads, max_upload_size.to_i
105
- end
106
-
107
- def write_page(web_address, page_name, content, written_on, author)
108
- page = Page.new(@webs[web_address], page_name, content, written_on, author)
109
- @webs[web_address].add_page(page)
110
- page
111
- end
112
-
113
- def storage_path
114
- self.class.storage_path
115
- end
116
-
117
- private
118
- def settings_changed?(web, markup, safe_mode, brackets_only)
119
- web.markup != markup ||
120
- web.safe_mode != safe_mode ||
121
- web.brackets_only != brackets_only
122
- end
123
- end
124
-
125
- class WikiService
126
-
127
- include AbstractWikiService
128
- include Madeleine::Automatic::Interceptor
129
-
130
- # These methods do not change the state of persistent objects, and
131
- # should not be ogged by Madeleine
132
- automatic_read_only :authenticate, :read_page, :setup?, :webs, :storage_path, :file_yard
133
-
134
- @@storage_path = './storage/'
135
-
136
- class << self
137
-
138
- def storage_path=(storage_path)
139
- @@storage_path = storage_path
140
- end
141
-
142
- def storage_path
143
- @@storage_path
144
- end
145
-
146
- def clean_storage
147
- MadeleineServer.clean_storage(self)
148
- end
149
-
150
- def instance
151
- @madeleine ||= MadeleineServer.new(self)
152
- @system = @madeleine.system
153
- return @system
154
- end
155
-
156
- def snapshot
157
- @madeleine.snapshot
158
- end
159
-
160
- end
161
-
162
- def initialize
163
- init_wiki_service
164
- end
165
-
166
- end
167
-
168
- class MadeleineServer
169
-
170
- attr_reader :storage_path
171
-
172
- # Clears all the command_log and snapshot files located in the storage directory, so the
173
- # database is essentially dropped and recreated as blank
174
- def self.clean_storage(service)
175
- begin
176
- Dir.foreach(service.storage_path) do |file|
177
- if file =~ /(command_log|snapshot)$/
178
- File.delete(File.join(service.storage_path, file))
179
- end
180
- end
181
- rescue
182
- Dir.mkdir(service.storage_path)
183
- end
184
- end
185
-
186
- def initialize(service)
187
- @storage_path = service.storage_path
188
- @server = Madeleine::Automatic::AutomaticSnapshotMadeleine.new(service.storage_path,
189
- Madeleine::ZMarshal.new) {
190
- service.new
191
- }
192
- start_snapshot_thread
193
- end
194
-
195
- def command_log_present?
196
- not Dir[storage_path + '/*.command_log'].empty?
197
- end
198
-
199
- def snapshot
200
- @server.take_snapshot
201
- end
202
-
203
- def start_snapshot_thread
204
- Thread.new(@server) {
205
- hours_since_last_snapshot = 0
206
- while true
207
- begin
208
- hours_since_last_snapshot += 1
209
- # Take a snapshot if there is a command log, or 24 hours
210
- # have passed since the last snapshot
211
- if command_log_present? or hours_since_last_snapshot >= 24
212
- ActionController::Base.logger.info "[#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] " +
213
- 'Taking a Madeleine snapshot'
214
- snapshot
215
- hours_since_last_snapshot = 0
216
- end
217
- sleep(1.hour)
218
- rescue => e
219
- ActionController::Base.logger.error(e)
220
- # wait for a minute (not to spoof the log with the same error)
221
- # and go back into the loop, to keep trying
222
- sleep(1.minute)
223
- ActionController::Base.logger.info("Retrying to save a snapshot")
224
- end
225
- end
226
- }
227
- end
228
-
229
- def system
230
- @server.system
231
- end
232
-
233
- end
1
+ require 'open-uri'
2
+ require 'yaml'
3
+ require 'madeleine'
4
+ require 'madeleine/automatic'
5
+ require 'madeleine/zmarshal'
6
+
7
+ require 'web'
8
+ require 'page'
9
+ require 'author'
10
+ require 'file_yard'
11
+ require 'instiki_errors'
12
+
13
+ module AbstractWikiService
14
+
15
+ attr_reader :webs, :system
16
+
17
+ def authenticate(password)
18
+ # system['password'] variant is for compatibility with storages from older versions
19
+ password == (@system[:password] || @system['password'] || 'instiki')
20
+ end
21
+
22
+ def create_web(name, address, password = nil)
23
+ @webs[address] = Web.new(self, name, address, password) unless @webs[address]
24
+ end
25
+
26
+ def delete_web(address)
27
+ @webs[address] = nil
28
+ end
29
+
30
+ def file_yard(web)
31
+ raise "Web #{@web.name} does not belong to this wiki service" unless @webs.values.include?(web)
32
+ # TODO cache FileYards
33
+ FileYard.new("#{self.storage_path}/#{web.address}", web.max_upload_size)
34
+ end
35
+
36
+ def init_wiki_service
37
+ @webs = {}
38
+ @system = {}
39
+ end
40
+
41
+ def read_page(web_address, page_name)
42
+ ApplicationController.logger.debug "Reading page '#{page_name}' from web '#{web_address}'"
43
+ web = @webs[web_address]
44
+ if web.nil?
45
+ ApplicationController.logger.debug "Web '#{web_address}' not found"
46
+ return nil
47
+ else
48
+ page = web.pages[page_name]
49
+ ApplicationController.logger.debug "Page '#{page_name}' #{page.nil? ? 'not' : ''} found"
50
+ return page
51
+ end
52
+ end
53
+
54
+ def remove_orphaned_pages(web_address)
55
+ @webs[web_address].remove_pages(@webs[web_address].select.orphaned_pages)
56
+ end
57
+
58
+ def revise_page(web_address, page_name, content, revised_on, author)
59
+ page = read_page(web_address, page_name)
60
+ page.revise(content, revised_on, author)
61
+ page
62
+ end
63
+
64
+ def rollback_page(web_address, page_name, revision_number, created_at, author_id = nil)
65
+ page = read_page(web_address, page_name)
66
+ page.rollback(revision_number, created_at, author_id)
67
+ page
68
+ end
69
+
70
+ def setup(password, web_name, web_address)
71
+ @system[:password] = password
72
+ create_web(web_name, web_address)
73
+ end
74
+
75
+ def setup?
76
+ not (@webs.empty?)
77
+ end
78
+
79
+ def edit_web(old_address, new_address, name, markup, color, additional_style, safe_mode = false,
80
+ password = nil, published = false, brackets_only = false, count_pages = false,
81
+ allow_uploads = true, max_upload_size = nil)
82
+
83
+ if not @webs.key? old_address
84
+ raise Instiki::ValidationError.new("Web with address '#{old_address}' does not exist")
85
+ end
86
+
87
+ if old_address != new_address
88
+ if @webs.key? new_address
89
+ raise Instiki::ValidationError.new("There is already a web with address '#{new_address}'")
90
+ end
91
+ @webs[new_address] = @webs[old_address]
92
+ @webs.delete(old_address)
93
+ @webs[new_address].address = new_address
94
+ end
95
+
96
+ web = @webs[new_address]
97
+ web.refresh_revisions if settings_changed?(web, markup, safe_mode, brackets_only)
98
+
99
+ web.name, web.markup, web.color, web.additional_style, web.safe_mode =
100
+ name, markup, color, additional_style, safe_mode
101
+
102
+ web.password, web.published, web.brackets_only, web.count_pages =
103
+ password, published, brackets_only, count_pages, allow_uploads
104
+ web.allow_uploads, web.max_upload_size = allow_uploads, max_upload_size.to_i
105
+ end
106
+
107
+ def write_page(web_address, page_name, content, written_on, author)
108
+ page = Page.new(@webs[web_address], page_name, content, written_on, author)
109
+ @webs[web_address].add_page(page)
110
+ page
111
+ end
112
+
113
+ def storage_path
114
+ self.class.storage_path
115
+ end
116
+
117
+ private
118
+ def settings_changed?(web, markup, safe_mode, brackets_only)
119
+ web.markup != markup ||
120
+ web.safe_mode != safe_mode ||
121
+ web.brackets_only != brackets_only
122
+ end
123
+ end
124
+
125
+ class WikiService
126
+
127
+ include AbstractWikiService
128
+ include Madeleine::Automatic::Interceptor
129
+
130
+ # These methods do not change the state of persistent objects, and
131
+ # should not be logged by Madeleine
132
+ automatic_read_only :authenticate, :read_page, :setup?, :webs, :storage_path, :file_yard
133
+
134
+ @@storage_path = './storage/'
135
+
136
+ class << self
137
+
138
+ def storage_path=(storage_path)
139
+ @@storage_path = storage_path
140
+ end
141
+
142
+ def storage_path
143
+ @@storage_path
144
+ end
145
+
146
+ def clean_storage
147
+ MadeleineServer.clean_storage(self)
148
+ end
149
+
150
+ def instance
151
+ @madeleine ||= MadeleineServer.new(self)
152
+ @system = @madeleine.system
153
+ return @system
154
+ end
155
+
156
+ def snapshot
157
+ @madeleine.snapshot
158
+ end
159
+
160
+ end
161
+
162
+ def initialize
163
+ init_wiki_service
164
+ end
165
+
166
+ end
167
+
168
+ class MadeleineServer
169
+
170
+ attr_reader :storage_path
171
+
172
+ # Clears all the command_log and snapshot files located in the storage directory, so the
173
+ # database is essentially dropped and recreated as blank
174
+ def self.clean_storage(service)
175
+ begin
176
+ Dir.foreach(service.storage_path) do |file|
177
+ if file =~ /(command_log|snapshot)$/
178
+ File.delete(File.join(service.storage_path, file))
179
+ end
180
+ end
181
+ rescue
182
+ Dir.mkdir(service.storage_path)
183
+ end
184
+ end
185
+
186
+ def initialize(service)
187
+ @storage_path = service.storage_path
188
+ @server = Madeleine::Automatic::AutomaticSnapshotMadeleine.new(service.storage_path,
189
+ Madeleine::ZMarshal.new) {
190
+ service.new
191
+ }
192
+ start_snapshot_thread
193
+ end
194
+
195
+ def command_log_present?
196
+ not Dir[storage_path + '/*.command_log'].empty?
197
+ end
198
+
199
+ def snapshot
200
+ @server.take_snapshot
201
+ end
202
+
203
+ def start_snapshot_thread
204
+ Thread.new(@server) {
205
+ hours_since_last_snapshot = 0
206
+ while true
207
+ begin
208
+ hours_since_last_snapshot += 1
209
+ # Take a snapshot if there is a command log, or 24 hours
210
+ # have passed since the last snapshot
211
+ if command_log_present? or hours_since_last_snapshot >= 24
212
+ ActionController::Base.logger.info "[#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] " +
213
+ 'Taking a Madeleine snapshot'
214
+ snapshot
215
+ hours_since_last_snapshot = 0
216
+ end
217
+ sleep(1.hour)
218
+ rescue => e
219
+ ActionController::Base.logger.error(e)
220
+ # wait for a minute (not to spoof the log with the same error)
221
+ # and go back into the loop, to keep trying
222
+ sleep(1.minute)
223
+ ActionController::Base.logger.info("Retrying to save a snapshot")
224
+ end
225
+ end
226
+ }
227
+ end
228
+
229
+ def system
230
+ @server.system
231
+ end
232
+
233
+ end