instiki 0.10.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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