olelo 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (282) hide show
  1. data/.gitignore +10 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +3 -0
  4. data/README.markdown +104 -0
  5. data/Rakefile +92 -0
  6. data/bin/olelo +5 -0
  7. data/config.ru +86 -0
  8. data/config/aspects.rb +256 -0
  9. data/config/config.yml.default +154 -0
  10. data/config/initializers/00-mime_types.rb +29 -0
  11. data/config/initializers/01-slim.rb +2 -0
  12. data/config/interwiki.yml +11 -0
  13. data/doc/AUTHORS +7 -0
  14. data/doc/LICENSE +22 -0
  15. data/lib/olelo.rb +39 -0
  16. data/lib/olelo/application.rb +294 -0
  17. data/lib/olelo/attributes.rb +285 -0
  18. data/lib/olelo/config.rb +88 -0
  19. data/lib/olelo/extensions.rb +252 -0
  20. data/lib/olelo/helper.rb +290 -0
  21. data/lib/olelo/hooks.rb +142 -0
  22. data/lib/olelo/html_safe.rb +29 -0
  23. data/lib/olelo/initializer.rb +76 -0
  24. data/lib/olelo/locale.rb +63 -0
  25. data/lib/olelo/locale.yml +284 -0
  26. data/lib/olelo/menu.rb +101 -0
  27. data/lib/olelo/middleware/blacklist.rb +25 -0
  28. data/lib/olelo/middleware/degrade_mime_type.rb +19 -0
  29. data/lib/olelo/middleware/flash.rb +97 -0
  30. data/lib/olelo/middleware/force_encoding.rb +41 -0
  31. data/lib/olelo/page.rb +266 -0
  32. data/lib/olelo/patch.rb +311 -0
  33. data/lib/olelo/plugin.rb +188 -0
  34. data/lib/olelo/repository.rb +225 -0
  35. data/lib/olelo/routing.rb +223 -0
  36. data/lib/olelo/templates.rb +30 -0
  37. data/lib/olelo/user.rb +132 -0
  38. data/lib/olelo/util.rb +233 -0
  39. data/lib/olelo/version.rb +3 -0
  40. data/lib/olelo/virtualfs.rb +161 -0
  41. data/lib/rack/olelo_patches.rb +33 -0
  42. data/lib/rack/relative_redirect.rb +44 -0
  43. data/lib/rack/static_cache.rb +93 -0
  44. data/lib/yard/addons.rb +1 -0
  45. data/lib/yard/addons/hook_handler.rb +25 -0
  46. data/lib/yard/addons/override_tag.rb +14 -0
  47. data/lib/yard/addons/route_handler.rb +33 -0
  48. data/lib/yard/addons/sanitize_anchor.rb +16 -0
  49. data/olelo.gemspec +31 -0
  50. data/plugins/aspects/changelog.rb +45 -0
  51. data/plugins/aspects/documentbrowser.rb +57 -0
  52. data/plugins/aspects/download.rb +11 -0
  53. data/plugins/aspects/highlight.rb +8 -0
  54. data/plugins/aspects/image.rb +41 -0
  55. data/plugins/aspects/imageinfo.rb +64 -0
  56. data/plugins/aspects/locale.yml +60 -0
  57. data/plugins/aspects/main.rb +199 -0
  58. data/plugins/aspects/pageinfo.rb +37 -0
  59. data/plugins/aspects/source.rb +6 -0
  60. data/plugins/aspects/subpages.rb +44 -0
  61. data/plugins/aspects/text.rb +9 -0
  62. data/plugins/blog/blog.css +1 -0
  63. data/plugins/blog/blog.scss +37 -0
  64. data/plugins/blog/locale.yml +12 -0
  65. data/plugins/blog/main.rb +85 -0
  66. data/plugins/editor/locale.yml +18 -0
  67. data/plugins/editor/markup/main.rb +3 -0
  68. data/plugins/editor/markup/script.js +10 -0
  69. data/plugins/editor/markup/script/00-jquery.textselection.js +267 -0
  70. data/plugins/editor/markup/script/01-olelo.markupeditor.js +116 -0
  71. data/plugins/editor/markup/script/init.js +10 -0
  72. data/plugins/editor/preview.rb +52 -0
  73. data/plugins/editor/recaptcha.rb +56 -0
  74. data/plugins/filters/creole.rb +37 -0
  75. data/plugins/filters/disposition.rb +9 -0
  76. data/plugins/filters/editsection.rb +67 -0
  77. data/plugins/filters/fix_img_tag.rb +16 -0
  78. data/plugins/filters/html_wrapper.rb +12 -0
  79. data/plugins/filters/interwiki.rb +19 -0
  80. data/plugins/filters/link_classifier.rb +26 -0
  81. data/plugins/filters/locale.yml +15 -0
  82. data/plugins/filters/main.rb +202 -0
  83. data/plugins/filters/markdown_nowiki.rb +15 -0
  84. data/plugins/filters/numbering.xsl +93 -0
  85. data/plugins/filters/orgmode.rb +6 -0
  86. data/plugins/filters/rubypants.rb +6 -0
  87. data/plugins/filters/s5/main.rb +32 -0
  88. data/plugins/filters/s5/s5.xsl +118 -0
  89. data/plugins/filters/tilt.rb +17 -0
  90. data/plugins/filters/toc.rb +50 -0
  91. data/plugins/filters/xhtml2latex.xsl +232 -0
  92. data/plugins/filters/xslt.rb +22 -0
  93. data/plugins/gallery/gallery.css +1 -0
  94. data/plugins/gallery/gallery.scss +28 -0
  95. data/plugins/gallery/main.rb +34 -0
  96. data/plugins/misc/fancybox/images/blank.gif +0 -0
  97. data/plugins/misc/fancybox/images/fancy_close.png +0 -0
  98. data/plugins/misc/fancybox/images/fancy_loading.png +0 -0
  99. data/plugins/misc/fancybox/images/fancy_nav_left.png +0 -0
  100. data/plugins/misc/fancybox/images/fancy_nav_right.png +0 -0
  101. data/plugins/misc/fancybox/images/fancy_shadow_e.png +0 -0
  102. data/plugins/misc/fancybox/images/fancy_shadow_n.png +0 -0
  103. data/plugins/misc/fancybox/images/fancy_shadow_ne.png +0 -0
  104. data/plugins/misc/fancybox/images/fancy_shadow_nw.png +0 -0
  105. data/plugins/misc/fancybox/images/fancy_shadow_s.png +0 -0
  106. data/plugins/misc/fancybox/images/fancy_shadow_se.png +0 -0
  107. data/plugins/misc/fancybox/images/fancy_shadow_sw.png +0 -0
  108. data/plugins/misc/fancybox/images/fancy_shadow_w.png +0 -0
  109. data/plugins/misc/fancybox/images/fancy_title_left.png +0 -0
  110. data/plugins/misc/fancybox/images/fancy_title_main.png +0 -0
  111. data/plugins/misc/fancybox/images/fancy_title_over.png +0 -0
  112. data/plugins/misc/fancybox/images/fancy_title_right.png +0 -0
  113. data/plugins/misc/fancybox/images/fancybox-x.png +0 -0
  114. data/plugins/misc/fancybox/images/fancybox-y.png +0 -0
  115. data/plugins/misc/fancybox/images/fancybox.png +0 -0
  116. data/plugins/misc/fancybox/jquery.fancybox.css +1 -0
  117. data/plugins/misc/fancybox/jquery.fancybox.scss +323 -0
  118. data/plugins/misc/fancybox/main.rb +4 -0
  119. data/plugins/misc/fancybox/script.js +37 -0
  120. data/plugins/misc/fancybox/script/00-jquery.mousewheel.js +84 -0
  121. data/plugins/misc/fancybox/script/01-jquery.easing.js +205 -0
  122. data/plugins/misc/fancybox/script/02-jquery.fancybox.js +1156 -0
  123. data/plugins/misc/fancybox/script/init.js +18 -0
  124. data/plugins/misc/system.rb +192 -0
  125. data/plugins/misc/variables.rb +29 -0
  126. data/plugins/misc/webdav.rb +45 -0
  127. data/plugins/repositories/git_grep.rb +69 -0
  128. data/plugins/repositories/gitrb_repository.rb +204 -0
  129. data/plugins/repositories/locale.yml +12 -0
  130. data/plugins/repositories/rugged_repository.rb +454 -0
  131. data/plugins/security/acl.rb +57 -0
  132. data/plugins/security/basic_auth.rb +21 -0
  133. data/plugins/security/locale.yml +21 -0
  134. data/plugins/security/persistent_login.rb +32 -0
  135. data/plugins/security/portal.rb +28 -0
  136. data/plugins/security/private_wiki.rb +24 -0
  137. data/plugins/security/readonly_wiki.rb +25 -0
  138. data/plugins/security/stack.rb +20 -0
  139. data/plugins/security/yamlfile.rb +66 -0
  140. data/plugins/tags/code.rb +6 -0
  141. data/plugins/tags/footnotes.rb +35 -0
  142. data/plugins/tags/gist-embed.css +123 -0
  143. data/plugins/tags/gist.rb +13 -0
  144. data/plugins/tags/html.rb +57 -0
  145. data/plugins/tags/include.rb +20 -0
  146. data/plugins/tags/main.rb +353 -0
  147. data/plugins/tags/math.rb +117 -0
  148. data/plugins/tags/scripting.rb +64 -0
  149. data/plugins/tags/sort.rb +7 -0
  150. data/plugins/tags/tabs.rb +20 -0
  151. data/plugins/treeview/images/collapsed.png +0 -0
  152. data/plugins/treeview/images/expanded.png +0 -0
  153. data/plugins/treeview/images/menu.png +0 -0
  154. data/plugins/treeview/images/tree.png +0 -0
  155. data/plugins/treeview/images/wait.gif +0 -0
  156. data/plugins/treeview/main.rb +16 -0
  157. data/plugins/treeview/script.js +5 -0
  158. data/plugins/treeview/script/00-jquery.treeview.js +164 -0
  159. data/plugins/treeview/script/init.js +25 -0
  160. data/plugins/treeview/treeview.css +1 -0
  161. data/plugins/treeview/treeview.scss +113 -0
  162. data/plugins/utils/assets.rb +74 -0
  163. data/plugins/utils/cache.rb +53 -0
  164. data/plugins/utils/image_magick.rb +34 -0
  165. data/plugins/utils/pygments.css +1 -0
  166. data/plugins/utils/pygments.rb +50 -0
  167. data/plugins/utils/pygments.scss +83 -0
  168. data/plugins/utils/semaphore.rb +50 -0
  169. data/plugins/utils/shell.rb +45 -0
  170. data/plugins/utils/store.rb +315 -0
  171. data/plugins/utils/worker.rb +36 -0
  172. data/plugins/utils/xml.rb +29 -0
  173. data/static/images/favicon.png +0 -0
  174. data/static/script.js +267 -0
  175. data/static/script/00-json2.js +486 -0
  176. data/static/script/01-jstorage.js +217 -0
  177. data/static/script/02-jquery.js +9440 -0
  178. data/static/script/03-jquery.ui.core.js +337 -0
  179. data/static/script/04-jquery.ui.widget.js +502 -0
  180. data/static/script/05-jquery.ui.position.js +517 -0
  181. data/static/script/06-jquery.ui.menu.js +609 -0
  182. data/static/script/07-jquery.ui.autocomplete.js +601 -0
  183. data/static/script/08-olelo.i18n.js +37 -0
  184. data/static/script/09-olelo.unsaved.js +68 -0
  185. data/static/script/10-olelo.historytable.js +40 -0
  186. data/static/script/11-olelo.pagination.js +18 -0
  187. data/static/script/13-olelo.tabwidget.js +57 -0
  188. data/static/script/14-olelo.timeago.js +70 -0
  189. data/static/script/15-olelo.underliner.js +31 -0
  190. data/static/script/16-olelo.ui.combobox.js +32 -0
  191. data/static/script/init.js +48 -0
  192. data/static/themes/atlantis/constants.scss +15 -0
  193. data/static/themes/atlantis/iehacks.scss +38 -0
  194. data/static/themes/atlantis/images/actions/delete.png +0 -0
  195. data/static/themes/atlantis/images/actions/edit.png +0 -0
  196. data/static/themes/atlantis/images/actions/history.png +0 -0
  197. data/static/themes/atlantis/images/actions/home.png +0 -0
  198. data/static/themes/atlantis/images/actions/move.png +0 -0
  199. data/static/themes/atlantis/images/actions/new.png +0 -0
  200. data/static/themes/atlantis/images/actions/page.png +0 -0
  201. data/static/themes/atlantis/images/bg/button.png +0 -0
  202. data/static/themes/atlantis/images/bg/container.png +0 -0
  203. data/static/themes/atlantis/images/bg/content.png +0 -0
  204. data/static/themes/atlantis/images/bg/footer.png +0 -0
  205. data/static/themes/atlantis/images/bg/header.jpg +0 -0
  206. data/static/themes/atlantis/images/bg/header.orig.jpg +0 -0
  207. data/static/themes/atlantis/images/bg/header_gray.jpg +0 -0
  208. data/static/themes/atlantis/images/bug.png +0 -0
  209. data/static/themes/atlantis/images/filetypes/7z.png +0 -0
  210. data/static/themes/atlantis/images/filetypes/_archive.png +0 -0
  211. data/static/themes/atlantis/images/filetypes/_audio.png +0 -0
  212. data/static/themes/atlantis/images/filetypes/_code.png +0 -0
  213. data/static/themes/atlantis/images/filetypes/_linux.png +0 -0
  214. data/static/themes/atlantis/images/filetypes/_picture.png +0 -0
  215. data/static/themes/atlantis/images/filetypes/_video.png +0 -0
  216. data/static/themes/atlantis/images/filetypes/bz2.png +0 -0
  217. data/static/themes/atlantis/images/filetypes/doc.png +0 -0
  218. data/static/themes/atlantis/images/filetypes/flac.png +0 -0
  219. data/static/themes/atlantis/images/filetypes/gz.png +0 -0
  220. data/static/themes/atlantis/images/filetypes/html.png +0 -0
  221. data/static/themes/atlantis/images/filetypes/java.png +0 -0
  222. data/static/themes/atlantis/images/filetypes/jpg.png +0 -0
  223. data/static/themes/atlantis/images/filetypes/midi.png +0 -0
  224. data/static/themes/atlantis/images/filetypes/mp3.png +0 -0
  225. data/static/themes/atlantis/images/filetypes/ogg.png +0 -0
  226. data/static/themes/atlantis/images/filetypes/pdf.png +0 -0
  227. data/static/themes/atlantis/images/filetypes/php.png +0 -0
  228. data/static/themes/atlantis/images/filetypes/png.png +0 -0
  229. data/static/themes/atlantis/images/filetypes/ppt.png +0 -0
  230. data/static/themes/atlantis/images/filetypes/psd.png +0 -0
  231. data/static/themes/atlantis/images/filetypes/rar.png +0 -0
  232. data/static/themes/atlantis/images/filetypes/rb.png +0 -0
  233. data/static/themes/atlantis/images/filetypes/sh.png +0 -0
  234. data/static/themes/atlantis/images/filetypes/tar.png +0 -0
  235. data/static/themes/atlantis/images/filetypes/txt.png +0 -0
  236. data/static/themes/atlantis/images/filetypes/wma.png +0 -0
  237. data/static/themes/atlantis/images/filetypes/xls.png +0 -0
  238. data/static/themes/atlantis/images/filetypes/zip.png +0 -0
  239. data/static/themes/atlantis/images/folder.png +0 -0
  240. data/static/themes/atlantis/images/folder_open.png +0 -0
  241. data/static/themes/atlantis/images/loading.gif +0 -0
  242. data/static/themes/atlantis/images/loading.xcf +0 -0
  243. data/static/themes/atlantis/images/not_found.png +0 -0
  244. data/static/themes/atlantis/images/page.png +0 -0
  245. data/static/themes/atlantis/images/search.png +0 -0
  246. data/static/themes/atlantis/layout.scss +115 -0
  247. data/static/themes/atlantis/menu.scss +99 -0
  248. data/static/themes/atlantis/print.scss +129 -0
  249. data/static/themes/atlantis/screen.scss +495 -0
  250. data/static/themes/atlantis/style.css +3 -0
  251. data/static/themes/lib/autocomplete.scss +39 -0
  252. data/static/themes/lib/headlines.scss +10 -0
  253. data/static/themes/lib/horizontal-list.scss +31 -0
  254. data/static/themes/lib/patch.scss +88 -0
  255. data/static/themes/lib/reset.scss +114 -0
  256. data/static/themes/lib/rounded.scss +46 -0
  257. data/static/themes/lib/shadow.scss +14 -0
  258. data/test/config_test.rb +28 -0
  259. data/test/factory_test.rb +29 -0
  260. data/test/hash_extensions_test.rb +16 -0
  261. data/test/helper.rb +38 -0
  262. data/test/hooks_test.rb +85 -0
  263. data/test/object_extensions_test.rb +20 -0
  264. data/test/page_test.rb +168 -0
  265. data/test/request_test.rb +166 -0
  266. data/test/string_extensions_test.rb +32 -0
  267. data/test/templates_test.rb +39 -0
  268. data/test/util_test.rb +71 -0
  269. data/views/changes.slim +22 -0
  270. data/views/compare.slim +8 -0
  271. data/views/delete.slim +9 -0
  272. data/views/deleted.slim +2 -0
  273. data/views/edit.slim +65 -0
  274. data/views/error.slim +6 -0
  275. data/views/history.slim +20 -0
  276. data/views/layout.slim +38 -0
  277. data/views/login.slim +37 -0
  278. data/views/move.slim +10 -0
  279. data/views/not_found.slim +6 -0
  280. data/views/profile.slim +26 -0
  281. data/views/show.slim +9 -0
  282. metadata +488 -0
@@ -0,0 +1,18 @@
1
+ (function() {
2
+ function initFancybox() {
3
+ $('a.fancybox').each(function() {
4
+ var href = this.href.replace(/aspect=\w+/g, '');
5
+ this.href = href + (href.indexOf('?') < 0 ? '?' : '&') + 'aspect=image&geometry=800x800>';
6
+ });
7
+ $('a.fancybox').fancybox({
8
+ 'transitionIn' : 'none',
9
+ 'transitionOut' : 'none',
10
+ 'titlePosition' : 'over',
11
+ 'titleFormat' : function(title, currentArray, currentIndex, currentOpts) {
12
+ return '<span id="fancybox-title-over">' + (currentIndex + 1) + ' / ' + currentArray.length + ' ' + (title ? title : '') + '</span>';
13
+ }});
14
+ }
15
+
16
+ $('#content').bind('pageLoaded', initFancybox);
17
+ initFancybox();
18
+ })();
@@ -0,0 +1,192 @@
1
+ description 'System information'
2
+
3
+ class ::Olelo::Application
4
+ get '/system' do
5
+ GC.start
6
+ @memory = `ps -o rss= -p #{$$}`.to_i / 1024
7
+ render :system
8
+ end
9
+
10
+ def check_mark(value)
11
+ value ? '&#x2713;' : ''
12
+ end
13
+ end
14
+
15
+ __END__
16
+ @@ system.slim
17
+ - title 'System Information'
18
+ h1 System Information
19
+ ul.tabs
20
+ li#tabhead-runtime
21
+ a href="#tab-runtime" Runtime
22
+ li#tabhead-configuration
23
+ a href="#tab-configuration" Configuration
24
+ li#tabhead-plugins
25
+ a href="#tab-plugins" Plugins
26
+ - if defined?(Olelo::Plugin::Aspects::Aspect)
27
+ li#tabhead-aspects
28
+ a href="#tab-aspects" Aspects
29
+ - if defined?(Olelo::Plugin::Filters::Filter)
30
+ li#tabhead-filters
31
+ a href="#tab-filters" Filters
32
+ - if defined?(Olelo::Plugin::Tags::Tag)
33
+ li#tabhead-tags
34
+ a href="#tab-tags" Tags
35
+ #tab-runtime.tab
36
+ h2 Runtime
37
+ table
38
+ tr
39
+ td &#332;lelo version:
40
+ td= Olelo::VERSION
41
+ tr
42
+ td Ruby version:
43
+ td= RUBY_VERSION
44
+ tr
45
+ td Memory usage:
46
+ td #{@memory} MiB
47
+ - if defined?(Olelo::Worker)
48
+ tr
49
+ td Worker jobs
50
+ td= Olelo::Worker.jobs
51
+ #tab-configuration.tab
52
+ h2 Configuration
53
+ table
54
+ tr
55
+ td Production mode:
56
+ td= Olelo::Config['production']
57
+ tr
58
+ td Repository backend:
59
+ td= Olelo::Config['repository.type']
60
+ tr
61
+ td Authentication backend:
62
+ td= Olelo::Config['authentication.service']
63
+ tr
64
+ td Locale:
65
+ td= Olelo::Config['locale']
66
+ tr
67
+ td Base path:
68
+ td= Olelo::Config['base_path']
69
+ tr
70
+ td Log level:
71
+ td= Olelo::Config['log.level']
72
+ tr
73
+ td Sidebar page:
74
+ td
75
+ a href=build_path(Olelo::Config['sidebar_page']) = Olelo::Config['sidebar_page']
76
+ tr
77
+ td Mime type detection order:
78
+ td= Olelo::Config['mime'].join(', ')
79
+ #tab-plugins.tab
80
+ h2 Plugins
81
+ p These plugins are currently available on your installation.
82
+ table.full
83
+ thead
84
+ tr
85
+ th Name
86
+ th Description
87
+ th Dependencies
88
+ tbody
89
+ - Olelo::Plugin.loaded.sort_by(&:path).each do |plugin|
90
+ tr
91
+ td= plugin.path
92
+ td= plugin.description
93
+ td= plugin.dependencies.to_a.join(', ')
94
+ - Olelo::Plugin.disabled.sort.each do |plugin|
95
+ tr
96
+ td #{plugin} (disabled)
97
+ td unknown
98
+ td unknown
99
+ - Olelo::Plugin.failed.sort.each do |plugin|
100
+ tr
101
+ td #{plugin} (failed)
102
+ td unknown
103
+ td unknown
104
+ - if defined?(Olelo::Plugin::Aspects::Aspect)
105
+ #tab-aspects.tab
106
+ h2 Aspects
107
+ p
108
+ | Every page is rendered by an aspect. The default aspect is selected automatically,
109
+ where aspects with lower priority are preferred. An alternative aspect
110
+ can be selected using the view menu or manually using the "aspect" query parameter.
111
+ .scrollable
112
+ table.full
113
+ thead
114
+ tr
115
+ th Name
116
+ th Description
117
+ th Output Mime Type
118
+ th Accepted mime types
119
+ th Hidden
120
+ th Cacheable
121
+ th Layout
122
+ th Priority
123
+ th Provided by plugin
124
+ tbody
125
+ - Olelo::Plugin::Aspects::Aspect.aspects.values.flatten.sort_by(&:name).each do |aspect|
126
+ tr
127
+ td= aspect.name
128
+ td= aspect.description
129
+ td= aspect.mime
130
+ td= aspect.accepts ? aspect.accepts.inspect : '*'
131
+ td== check_mark aspect.hidden?
132
+ td== check_mark aspect.cacheable?
133
+ td== check_mark aspect.layout?
134
+ td= aspect.priority
135
+ td= aspect.plugin.path
136
+ - if defined?(Olelo::Plugin::Filters::Filter)
137
+ #tab-filters.tab
138
+ h2 Filters used by filter aspects
139
+ p Filters can be chained to build filter aspects.
140
+ table.full
141
+ thead
142
+ tr
143
+ th Name
144
+ th Description
145
+ th Subfilters
146
+ th Provided by plugin
147
+ tbody
148
+ - Olelo::Plugin::Filters::Filter.registry.values.sort_by(&:name).each do |filter|
149
+ tr
150
+ td= filter.name
151
+ td= filter.description
152
+ td== check_mark filter.respond_to?(:subfilter)
153
+ td= filter.plugin.path
154
+ h2 Filter aspect definitions
155
+ table.full
156
+ thead
157
+ tr
158
+ th Name
159
+ th Filters
160
+ tbody
161
+ - Olelo::Plugin::Aspects::Aspect.aspects.values.flatten.select {|aspect| Olelo::Plugin::Filters::FilterAspect === aspect }.sort_by(&:name).each do |aspect|
162
+ tr
163
+ td= aspect.name
164
+ td= aspect.definition
165
+ - if defined?(Olelo::Plugin::Tags::Tag)
166
+ #tab-tags.tab
167
+ h2 Tags
168
+ p
169
+ | Tags can be included in the wikitext like normal html tags. These tags are provided by plugins as wikitext extensions.
170
+ The namespace prefixes are optional and can be used in case of ambiguities.
171
+ table.full
172
+ thead
173
+ tr
174
+ th Name
175
+ th Description
176
+ th Immediate
177
+ th Dynamic
178
+ th Autoclose
179
+ th Provided by plugin
180
+ th Optional attributes
181
+ th Required attributes
182
+ tbody
183
+ - Olelo::Plugin::Tags::Tag.tags.values.uniq.sort_by(&:full_name).each do |tag|
184
+ tr
185
+ td= tag.full_name
186
+ td= tag.description
187
+ td== check_mark tag.immediate
188
+ td== check_mark tag.dynamic
189
+ td== check_mark tag.autoclose
190
+ td= tag.plugin.path
191
+ td= tag.optional.to_a.join(', ')
192
+ td= tag.requires.to_a.join(', ')
@@ -0,0 +1,29 @@
1
+ description 'Export variables to context and javascript'
2
+ dependencies 'aspects'
3
+
4
+ def self.exported_variables(page)
5
+ vars = {
6
+ 'page_name' => page.name,
7
+ 'page_new' => page.new?,
8
+ 'page_modified' => page.modified?,
9
+ 'page_path' => page.path,
10
+ 'page_title' => page.title,
11
+ 'page_version' => page.version.to_s,
12
+ 'page_next_version' => page.next_version.to_s,
13
+ 'page_previous_version' => page.previous_version.to_s,
14
+ 'page_mime' => page.mime.to_s,
15
+ 'default_mime' => Page.default_mime
16
+ }
17
+ end
18
+
19
+ # Export variables to aspect context
20
+ Aspects::Context.hook(:initialized) do
21
+ params.merge!(PLUGIN.exported_variables(page))
22
+ end
23
+
24
+ # Export variables to javascript for client extensions
25
+ Application.hook :head do
26
+ vars = page ? params.merge(PLUGIN.exported_variables(page)) : params
27
+ vars = vars.merge('user_logged_in' => !User.logged_in?, 'user_name' => User.current.name)
28
+ %{<script type="text/javascript">Olelo = #{escape_javascript(vars.to_json)};</script>}
29
+ end
@@ -0,0 +1,45 @@
1
+ description 'Simple webdav interface to the wiki files'
2
+
3
+ class ::Olelo::Application
4
+ def webdav_post
5
+ Page.transaction do
6
+ page = request.put? ? Page.find!(params[:path]) : Page.new(params[:path])
7
+ raise :reserved_path.t if self.class.reserved_path?(page.path)
8
+ page.content = request.body
9
+ page.save
10
+ Page.commit(:page_uploaded.t(:page => page.title))
11
+ :created
12
+ end
13
+ rescue NotFound => ex
14
+ Olelo.logger.error ex
15
+ :not_found
16
+ rescue Exception => ex
17
+ Olelo.logger.error ex
18
+ :bad_request
19
+ end
20
+
21
+ put '/(:path)', :tail => true do
22
+ if request.form_data?
23
+ :not_implemented
24
+ else
25
+ webdav_post
26
+ end
27
+ end
28
+
29
+ post '/(:path)', :tail => true do
30
+ if request.form_data?
31
+ super()
32
+ else
33
+ webdav_post
34
+ end
35
+ end
36
+
37
+ # TODO: Implement more methods if needed
38
+ add_route('PROPFIND', '/(:path)', :tail => true) { :not_found }
39
+ add_route('PROPPATCH', '/(:path)', :tail => true) { :not_implemented }
40
+ add_route('MKCOL', '/(:path)', :tail => true) { :not_implemented }
41
+ add_route('COPY', '/(:path)', :tail => true) { :not_implemented }
42
+ add_route('MOVE', '/(:path)', :tail => true) { :not_implemented }
43
+ add_route('LOCK', '/(:path)', :tail => true) { :not_implemented }
44
+ add_route('UNLOCK', '/(:path)', :tail => true) { :not_implemented }
45
+ end
@@ -0,0 +1,69 @@
1
+ description 'Searching via git-grep'
2
+
3
+ class ::Olelo::Application
4
+ get '/search' do
5
+ @matches = {}
6
+
7
+ if params[:pattern].to_s.length > 2
8
+ Repository.instance.git_grep('-z', '-i', '-I', '-3', '-e', params[:pattern], 'master') do |io|
9
+ while !io.eof?
10
+ begin
11
+ line = io.readline.force_encoding(Encoding.default_external)
12
+ line = unescape_backslash(line)
13
+ if line =~ /(.*?)\:([^\0]+)\0(.*)/
14
+ path, match = $2, $3
15
+ path = path.split('/')
16
+ path.pop if Repository.instance.reserved_name?(path.last)
17
+ path = path.join('/')
18
+ (@matches[path] ||= []) << match
19
+ end
20
+ rescue => ex
21
+ Olelo.logger.error ex
22
+ end
23
+ end
24
+ end rescue nil # git-grep returns 1 if nothing is found
25
+
26
+ Repository.instance.git_ls_tree('-r', '--name-only', 'HEAD') do |io|
27
+ while !io.eof?
28
+ begin
29
+ line = io.readline.force_encoding(Encoding.default_external)
30
+ line = unescape_backslash(line).strip
31
+ if line =~ /#{params[:pattern]}/i && !@matches[line]
32
+ path = line.split('/')
33
+ path.pop if Repository.instance.reserved_name?(path.last)
34
+ path = path.join('/')
35
+ page = Page.find!(path)
36
+ @matches[path] = [truncate(page.content, 500)] if page.mime.text?
37
+ end
38
+ rescue => ex
39
+ Olelo.logger.error ex
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ @matches = @matches.to_a.sort do |a,b|
46
+ a[1].length == b[1].length ? a[0] <=> b[0] : b[1].length <=> a[1].length
47
+ end.map {|path, content| [path, content.join] }
48
+
49
+ render :grep
50
+ end
51
+
52
+ private
53
+
54
+ def emphasize(s)
55
+ escape_html(truncate(s, 500)).gsub(/(#{params[:pattern]})/i, '<b>\1</b>').html_safe
56
+ end
57
+ end
58
+
59
+ __END__
60
+ @@ grep.slim
61
+ - title :search_results.t(:pattern => params[:pattern])
62
+ h1= title
63
+ p= :match.t(:count => @matches.length)
64
+ .search
65
+ - @matches.each do |path, content|
66
+ .match
67
+ h2
68
+ a.name href=build_path(path) = emphasize(path)
69
+ .content= emphasize(content)
@@ -0,0 +1,204 @@
1
+ description 'Git repository backend (Using gitrb library)'
2
+ require 'gitrb'
3
+
4
+ class GitrbRepository < Repository
5
+ CONTENT_EXT = '.content'
6
+ ATTRIBUTE_EXT = '.attributes'
7
+
8
+ def initialize(config)
9
+ Olelo.logger.info "Opening git repository: #{config[:path]}"
10
+ @git = Gitrb::Repository.new(:path => config[:path], :create => true,
11
+ :bare => config[:bare], :logger => Olelo.logger)
12
+ end
13
+
14
+ # @override
15
+ def transaction(&block)
16
+ @git.transaction(&block)
17
+ end
18
+
19
+ # @override
20
+ def commit(comment)
21
+ user = User.current
22
+ @git.commit(comment, user && Gitrb::User.new(user.name, user.email))
23
+ commit_to_version(@git.head)
24
+ end
25
+
26
+ # @override
27
+ def path_exists?(path, version)
28
+ check_path(path)
29
+ !get_object(path, version).nil? rescue false
30
+ end
31
+
32
+ # @override
33
+ def get_version(version)
34
+ commit_to_version(version ? (get_commit(version) rescue nil) : @git.head)
35
+ end
36
+
37
+ # @override
38
+ def get_history(path, skip, limit)
39
+ @git.log(:max_count => limit, :skip => skip,
40
+ :path => [path, path + ATTRIBUTE_EXT, path + CONTENT_EXT]).map do |c|
41
+ commit_to_version(c)
42
+ end
43
+ end
44
+
45
+ # @override
46
+ def get_path_version(path, version)
47
+ commits = @git.log(:max_count => 2, :start => version, :path => [path, path + ATTRIBUTE_EXT, path + CONTENT_EXT])
48
+
49
+ succ = nil
50
+ @git.git_rev_list('--reverse', '--remove-empty', "#{commits[0]}..", '--', path, path + ATTRIBUTE_EXT, path + CONTENT_EXT) do |io|
51
+ succ = io.eof? ? nil : get_commit(@git.set_encoding(io.readline).strip)
52
+ end rescue nil # no error because pipe is closed intentionally
53
+
54
+ # Deleted pages have next version (Issue #11)
55
+ succ = nil if succ && !path_exists?(path, succ.id)
56
+
57
+ [commit_to_version(commits[1]), # previous version
58
+ commit_to_version(commits[0]), # current version
59
+ commit_to_version(succ)] # next version
60
+ end
61
+
62
+ # @override
63
+ def get_children(path, version)
64
+ object = get_object(path, version)
65
+ object && object.type != :tree ? [] : object.names.reject {|name| reserved_name?(name) }
66
+ end
67
+
68
+ # @override
69
+ def get_content(path, version)
70
+ tree = get_commit(version).tree
71
+ object = tree[path]
72
+ object = tree[path + CONTENT_EXT] if object && object.type == :tree
73
+ if object
74
+ content = object.data
75
+ # Try to force utf-8 encoding and revert to old encoding if this doesn't work
76
+ content.try_encoding(Encoding.default_encoding)
77
+ else
78
+ ''
79
+ end
80
+ end
81
+
82
+ # @override
83
+ def get_attributes(path, version)
84
+ object = get_object(path + ATTRIBUTE_EXT, version)
85
+ object && object.type == :blob ? YAML.load(object.data) : {}
86
+ end
87
+
88
+ # @override
89
+ def set_content(path, content)
90
+ check_path(path)
91
+ content = content.read if content.respond_to? :read
92
+ expand_tree(path)
93
+ object = @git.root[path]
94
+ if object && object.type == :tree
95
+ if content.blank?
96
+ @git.root.delete(path + CONTENT_EXT)
97
+ else
98
+ @git.root[path + CONTENT_EXT] = Gitrb::Blob.new(:data => content)
99
+ end
100
+ collapse_empty_tree(path)
101
+ else
102
+ @git.root[path] = Gitrb::Blob.new(:data => content)
103
+ end
104
+ end
105
+
106
+ # @override
107
+ def set_attributes(path, attributes)
108
+ check_path(path)
109
+ attributes = attributes.blank? ? nil : YAML.dump(attributes).sub(/\A\-\-\-\s*\n/s, '')
110
+ expand_tree(path)
111
+ if attributes
112
+ @git.root[path + ATTRIBUTE_EXT] = Gitrb::Blob.new(:data => attributes)
113
+ else
114
+ @git.root.delete(path + ATTRIBUTE_EXT)
115
+ end
116
+ end
117
+
118
+ # @override
119
+ def move(path, destination)
120
+ check_path(destination)
121
+ @git.root.move(path, destination)
122
+ @git.root.move(path + CONTENT_EXT, destination + CONTENT_EXT) if @git.root[path + CONTENT_EXT]
123
+ @git.root.move(path + ATTRIBUTE_EXT, destination + ATTRIBUTE_EXT) if @git.root[path + ATTRIBUTE_EXT]
124
+ collapse_empty_tree(path/'..')
125
+ end
126
+
127
+ # @override
128
+ def delete(path)
129
+ @git.root.delete(path)
130
+ @git.root.delete(path + CONTENT_EXT)
131
+ @git.root.delete(path + ATTRIBUTE_EXT)
132
+ collapse_empty_tree(path/'..')
133
+ end
134
+
135
+ # @override
136
+ def diff(path, from, to)
137
+ diff = @git.diff(:from => from && from.to_s, :to => to.to_s,
138
+ :path => [path, path + CONTENT_EXT, path + ATTRIBUTE_EXT], :detect_renames => true)
139
+ Diff.new(commit_to_version(diff.from), commit_to_version(diff.to), diff.patch)
140
+ end
141
+
142
+ # @override
143
+ def short_version(version)
144
+ version[0..4]
145
+ end
146
+
147
+ def reserved_name?(name)
148
+ name.ends_with?(ATTRIBUTE_EXT) || name.ends_with?(CONTENT_EXT)
149
+ end
150
+
151
+ def method_missing(name, *args)
152
+ if cmd =~ /\Agit_/
153
+ @git.method_missing(name, *args)
154
+ else
155
+ super
156
+ end
157
+ end
158
+
159
+ private
160
+
161
+ def get_commit(version)
162
+ @git.get_commit(version.to_s)
163
+ end
164
+
165
+ def get_object(path, version)
166
+ @git.get_commit(version.to_s).tree[path]
167
+ end
168
+
169
+ def check_path(path)
170
+ raise :reserved_path.t if path.split('/').any? {|name| reserved_name?(name) }
171
+ end
172
+
173
+ def commit_to_version(commit)
174
+ commit && Version.new(commit.id, User.new(commit.author.name, commit.author.email),
175
+ commit.date, commit.message, commit.parents.map(&:id), commit == @git.head)
176
+ end
177
+
178
+ # Convert blob parents to trees
179
+ # to allow children
180
+ def expand_tree(path)
181
+ names = path.split('/')
182
+ names.pop
183
+ parent = @git.root
184
+ names.each do |name|
185
+ object = parent[name]
186
+ break if !object
187
+ if object.type == :blob
188
+ parent.move(name, name + CONTENT_EXT)
189
+ break
190
+ end
191
+ parent = object
192
+ end
193
+ end
194
+
195
+ # If a tree consists only of tree/, tree.content and tree.attributes without
196
+ # children, tree.content can be moved to tree ("collapsing").
197
+ def collapse_empty_tree(path)
198
+ if !path.blank? && @git.root[path].empty? && @git.root[path + CONTENT_EXT]
199
+ @git.root.move(path + CONTENT_EXT, path)
200
+ end
201
+ end
202
+ end
203
+
204
+ Repository.register :gitrb, GitrbRepository