zena 0.15.2 → 0.16.0

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 (284) hide show
  1. data/.gitignore +20 -0
  2. data/CREDITS +27 -0
  3. data/Capfile +3 -0
  4. data/DEVELOPERS +46 -0
  5. data/History.txt +15 -0
  6. data/MIT-LICENSE +19 -0
  7. data/Rakefile +44 -0
  8. data/TODO +24 -0
  9. data/TODO_ZENA_1_0 +23 -0
  10. data/app/controllers/application_controller.rb +3 -0
  11. data/app/controllers/documents_controller.rb +22 -56
  12. data/app/controllers/nodes_controller.rb +42 -27
  13. data/app/controllers/pings_controller.rb +19 -0
  14. data/app/controllers/relations_controller.rb +5 -1
  15. data/app/controllers/sites_controller.rb +1 -46
  16. data/app/controllers/user_sessions_controller.rb +47 -0
  17. data/app/controllers/users_controller.rb +1 -0
  18. data/app/controllers/versions_controller.rb +25 -7
  19. data/app/controllers/virtual_classes_controller.rb +1 -1
  20. data/app/helpers/application_helper.rb +1 -1
  21. data/app/models/comment.rb +2 -1
  22. data/app/models/contact_content.rb +2 -2
  23. data/app/models/data_entry.rb +5 -6
  24. data/app/models/document.rb +14 -10
  25. data/app/models/document_content.rb +4 -6
  26. data/app/models/iformat.rb +2 -2
  27. data/app/models/image_content.rb +6 -9
  28. data/app/models/node.rb +106 -164
  29. data/app/models/page.rb +0 -20
  30. data/app/models/site.rb +42 -12
  31. data/app/models/template.rb +3 -8
  32. data/app/models/template_content.rb +2 -0
  33. data/app/models/text_document.rb +13 -8
  34. data/app/models/user.rb +47 -100
  35. data/app/models/user_session.rb +4 -0
  36. data/app/models/version.rb +1 -1
  37. data/app/views/comments/create.rjs +3 -3
  38. data/app/views/comments/edit.rjs +1 -1
  39. data/app/views/comments/update.rjs +1 -1
  40. data/app/views/nodes/_import_results.rhtml +1 -1
  41. data/app/views/nodes/create.rjs +3 -3
  42. data/app/views/templates/document_create_tabs/_file.rhtml +1 -2
  43. data/app/views/templates/document_create_tabs/_import.rhtml +7 -2
  44. data/app/views/templates/edit_tabs/_document.rhtml +1 -3
  45. data/app/views/templates/edit_tabs/_image.rhtml +1 -3
  46. data/app/views/versions/_tr.rhtml +1 -1
  47. data/app/views/versions/edit.rhtml +2 -26
  48. data/bin/zena +6 -1
  49. data/bricks/delayed_job/README +18 -0
  50. data/bricks/delayed_job/migrate/20091104191643_create_delayed_jobs_table.rb +19 -0
  51. data/bricks/delayed_job/misc/init.rb +8 -0
  52. data/bricks/delayed_job/misc/tasks.rb +2 -0
  53. data/bricks/math/patch/application_helper.rb +1 -1
  54. data/bricks/sphinx/MIT-LICENSE +19 -0
  55. data/bricks/sphinx/README +19 -0
  56. data/bricks/sphinx/lib/use_sphinx.rb +78 -0
  57. data/bricks/sphinx/migrate/20091102171258_add_delta_for_sphinx.rb +9 -0
  58. data/bricks/sphinx/misc/deploy.rb +20 -0
  59. data/bricks/sphinx/misc/sphinx.yml +12 -0
  60. data/bricks/sphinx/misc/tasks.rb +21 -0
  61. data/bricks/sphinx/patch/node.rb +8 -0
  62. data/bricks/tags/lib/has_tags.rb +5 -3
  63. data/bricks/tags/test/zafu/tags.yml +13 -1
  64. data/config/bricks.yml +35 -0
  65. data/config/deploy.rb +8 -1
  66. data/config/environment.rb +1 -1
  67. data/config/environments/production.rb +1 -1
  68. data/config/gems.yml +28 -5
  69. data/config/sphinx.yml +12 -0
  70. data/db/init/base/skins/default/Node-+popupLayout.zafu +1 -16
  71. data/db/migrate/20091026161708_add_persistence_token.rb +13 -0
  72. data/db/migrate/20091101184952_add_session_table.rb +16 -0
  73. data/db/migrate/20091123175137_add_single_access_token.rb +9 -0
  74. data/db/migrate/20091124161608_rebuild_fullpath.rb +11 -0
  75. data/db/schema.rb +21 -8
  76. data/doc/README_FOR_APP +24 -0
  77. data/doc/fixtures.graffle +19568 -0
  78. data/doc/fixtures.pdf +0 -0
  79. data/doc/template/LICENSE +184 -0
  80. data/doc/template/README +37 -0
  81. data/doc/template/allison.css +283 -0
  82. data/doc/template/allison.js +307 -0
  83. data/doc/template/allison.rb +260 -0
  84. data/doc/template/cache/BODY +588 -0
  85. data/doc/template/cache/CLASS_INDEX +4 -0
  86. data/doc/template/cache/CLASS_PAGE +1 -0
  87. data/doc/template/cache/FILE_INDEX +4 -0
  88. data/doc/template/cache/FILE_PAGE +1 -0
  89. data/doc/template/cache/FONTS +1 -0
  90. data/doc/template/cache/FR_INDEX_BODY +1 -0
  91. data/doc/template/cache/IMGPATH +1 -0
  92. data/doc/template/cache/INDEX +1 -0
  93. data/doc/template/cache/JAVASCRIPT +307 -0
  94. data/doc/template/cache/METHOD_INDEX +4 -0
  95. data/doc/template/cache/METHOD_LIST +1 -0
  96. data/doc/template/cache/SRC_PAGE +1 -0
  97. data/doc/template/cache/STYLE +283 -0
  98. data/doc/template/cache/URL +1 -0
  99. data/doc/zafu_changes.yml +29 -0
  100. data/lib/base_additions.rb +1 -1
  101. data/lib/bricks.rb +9 -0
  102. data/lib/bricks/loader.rb +86 -0
  103. data/lib/bricks/requirements_validation.rb +71 -0
  104. data/lib/tasks/zena.rake +42 -4
  105. data/lib/zafu/action.rb +285 -0
  106. data/lib/zafu/ajax.rb +93 -0
  107. data/lib/zafu/attributes.rb +117 -0
  108. data/lib/zafu/calendar.rb +159 -0
  109. data/lib/zafu/context.rb +330 -0
  110. data/lib/zafu/core/html.rb +102 -0
  111. data/lib/zafu/core/move_to_parser.rb +167 -0
  112. data/lib/zafu/dates.rb +58 -0
  113. data/lib/zafu/display.rb +502 -0
  114. data/lib/zafu/eval.rb +66 -0
  115. data/lib/zafu/experimental.rb +66 -0
  116. data/lib/zafu/i18n.rb +64 -0
  117. data/lib/zafu/meta.rb +25 -0
  118. data/lib/zafu/refactor.rb +73 -0
  119. data/lib/zafu/support/context.rb +265 -0
  120. data/lib/zafu/support/dom.rb +145 -0
  121. data/lib/zafu/support/erb.rb +62 -0
  122. data/lib/zafu/support/flow.rb +401 -0
  123. data/lib/zafu/support/forms.rb +461 -0
  124. data/lib/zafu/support/links.rb +306 -0
  125. data/lib/zafu_parser.rb +26 -2
  126. data/lib/zena.rb +34 -15
  127. data/lib/zena/acts/multiversion.rb +2 -2
  128. data/lib/zena/acts/secure.rb +41 -30
  129. data/lib/zena/app.rb +7 -10
  130. data/lib/zena/controller/test_case.rb +12 -7
  131. data/lib/zena/crypto_provider/initial.rb +15 -0
  132. data/lib/zena/db.rb +6 -1
  133. data/lib/zena/deploy.rb +34 -6
  134. data/lib/zena/deploy/logrotate_app.rhtml +9 -0
  135. data/lib/zena/deploy/logrotate_host.rhtml +34 -0
  136. data/lib/zena/deploy/template.rb +1 -9
  137. data/lib/zena/foxy_parser.rb +1 -1
  138. data/lib/zena/info.rb +3 -1
  139. data/lib/zena/migrator.rb +1 -1
  140. data/lib/zena/parser.rb +12 -4
  141. data/lib/zena/parser/zazen_rules.rb +6 -6
  142. data/lib/zena/parser/zena_rules.rb +1 -7
  143. data/lib/zena/routes.rb +5 -5
  144. data/lib/zena/test_controller.rb +7 -2
  145. data/lib/zena/unit/test_case.rb +6 -8
  146. data/lib/zena/use/ajax.rb +10 -10
  147. data/lib/zena/use/authlogic.rb +93 -0
  148. data/lib/zena/use/dyn_attributes.rb +5 -0
  149. data/lib/zena/use/html_tags.rb +16 -34
  150. data/lib/zena/use/i18n.rb +4 -1
  151. data/lib/zena/use/node_query_finders.rb +8 -4
  152. data/lib/zena/use/refactor.rb +8 -20
  153. data/lib/zena/use/relations.rb +1 -0
  154. data/lib/zena/use/rendering.rb +4 -2
  155. data/lib/zena/use/search.rb +52 -0
  156. data/lib/zena/use/test_helper.rb +27 -28
  157. data/lib/zena/use/upload.rb +188 -0
  158. data/lib/zena/use/urls.rb +16 -14
  159. data/lib/zena/use/zafu.rb +16 -63
  160. data/lib/zena/use/zazen.rb +8 -8
  161. data/lib/zena/view/test_case.rb +8 -4
  162. data/locale/en/LC_MESSAGES/zena.mo +0 -0
  163. data/locale/en/zena.po +3 -3
  164. data/public/.htaccess +40 -0
  165. data/public/javascripts/upload-progress.js +17 -8
  166. data/public/javascripts/zena.js +8 -2
  167. data/public/stylesheets/popup.css +1 -0
  168. data/script/about +3 -0
  169. data/script/apache_logging +25 -0
  170. data/script/breakpointer +3 -0
  171. data/script/console +3 -0
  172. data/script/dbconsole +3 -0
  173. data/script/destroy +3 -0
  174. data/script/generate +3 -0
  175. data/script/performance/benchmarker +3 -0
  176. data/script/performance/profiler +3 -0
  177. data/script/plugin +3 -0
  178. data/script/process/inspector +3 -0
  179. data/script/process/reaper +3 -0
  180. data/script/process/spawner +3 -0
  181. data/script/runner +3 -0
  182. data/script/server +3 -0
  183. data/script/set_revision +29 -0
  184. data/spec/controllers/versions_controller_spec.rb +11 -0
  185. data/test/fixtures/files/Node-test.zafu +1 -1
  186. data/test/functional/nodes_controller_test.rb +25 -0
  187. data/test/functional/pings_controller_test.rb +8 -0
  188. data/test/functional/user_sessions_controller_test.rb +59 -0
  189. data/test/functional/users_controller_test.rb +81 -19
  190. data/test/helpers/node_query/filters.yml +5 -0
  191. data/test/helpers/node_query_test.rb +3 -3
  192. data/test/integration/multiple_hosts_test.rb +1 -1
  193. data/test/integration/navigation_test.rb +1 -1
  194. data/test/sites/complex/users.yml +1 -1
  195. data/test/sites/ocean/users.yml +3 -3
  196. data/test/sites/zena/users.yml +5 -4
  197. data/test/test_zena.rb +38 -38
  198. data/test/unit/cached_page_test.rb +2 -2
  199. data/test/unit/comment_test.rb +0 -1
  200. data/test/unit/document_test.rb +23 -11
  201. data/test/unit/helpers/ping_helper_test.rb +4 -0
  202. data/test/unit/multiversion_test.rb +24 -16
  203. data/test/unit/node_test.rb +32 -93
  204. data/test/unit/note_test.rb +9 -0
  205. data/test/unit/page_test.rb +2 -2
  206. data/test/unit/secure_test.rb +2 -12
  207. data/test/unit/site_test.rb +43 -24
  208. data/test/unit/template_test.rb +45 -3
  209. data/test/unit/text_document_test.rb +4 -3
  210. data/test/unit/user_test.rb +13 -33
  211. data/test/unit/zena/db_test.rb +8 -0
  212. data/test/unit/zena/parser/zazen.yml +4 -4
  213. data/test/unit/zena/use/dates_view_methods_test.rb +2 -1
  214. data/test/unit/zena/use/html_tags_test.rb +12 -4
  215. data/test/unit/zena/use/refactor_test.rb +4 -3
  216. data/test/unit/zena/use/rendering_test.rb +1 -0
  217. data/test/unit/zena/use/upload_test.rb +76 -0
  218. data/test/unit/zena/use/urls_test.rb +4 -0
  219. data/test/unit/zena/use/zafu_test.rb +8 -0
  220. data/test/unit/zena/workflow/status_version_test.rb +6 -0
  221. data/test/unit/zena/zena_tags/ajax.yml +4 -4
  222. data/test/unit/zena/zena_tags/basic.yml +21 -10
  223. data/test/unit/zena/zena_tags/relations.yml +0 -6
  224. data/test/unit/zena/zena_tags/rubyless.yml +35 -0
  225. data/test/unit/zena/zena_tags/zazen.yml +4 -4
  226. data/test/unit/zena/zena_tags_test.rb +36 -4
  227. data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +1 -1
  228. data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +2 -3
  229. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/catch_exception.rb +39 -0
  230. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +102 -58
  231. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/stdin_dialog.rb +14 -0
  232. data/vendor/TextMate/Zena.tmbundle/info.plist +2 -0
  233. data/zena.gemspec +2085 -0
  234. metadata +265 -90
  235. data/app/controllers/sessions_controller.rb +0 -41
  236. data/app/views/sites/zena_up.html.erb +0 -11
  237. data/config/database.yml +0 -40
  238. data/db/production.sqlite3 +0 -0
  239. data/lib/bricks/patcher.rb +0 -68
  240. data/lib/zena/parser/zena_tags.rb +0 -3562
  241. data/lib/zena/use/authentification.rb +0 -120
  242. data/public/images/ext/contact_pv.png +0 -0
  243. data/public/images/ext/other_pv.png +0 -0
  244. data/public/images/ext/page_pv.png +0 -0
  245. data/public/images/ext/page_tiny.png +0 -0
  246. data/public/images/ext/pdf_pv.png +0 -0
  247. data/public/images/ext/post_pv.png +0 -0
  248. data/public/images/ext/post_tiny.png +0 -0
  249. data/public/images/ext/project_pv.png +0 -0
  250. data/public/images/ext/project_tiny.png +0 -0
  251. data/public/images/ext/tag_pv.png +0 -0
  252. data/public/images/ext/zip_pv.png +0 -0
  253. data/tasks/ann.rake +0 -80
  254. data/tasks/bones.rake +0 -20
  255. data/tasks/gem.rake +0 -201
  256. data/tasks/git.rake +0 -40
  257. data/tasks/notes.rake +0 -27
  258. data/tasks/post_load.rake +0 -34
  259. data/tasks/rdoc.rake +0 -51
  260. data/tasks/rubyforge.rake +0 -55
  261. data/tasks/setup.rb +0 -292
  262. data/tasks/spec.rake +0 -54
  263. data/tasks/svn.rake +0 -47
  264. data/tasks/test.rake +0 -40
  265. data/tasks/zentest.rake +0 -36
  266. data/test/fixtures/comments.yml +0 -126
  267. data/test/fixtures/contact_contents.yml +0 -132
  268. data/test/fixtures/data_entries.yml +0 -65
  269. data/test/fixtures/discussions.yml +0 -48
  270. data/test/fixtures/document_contents.yml +0 -108
  271. data/test/fixtures/dyn_attributes.yml +0 -66
  272. data/test/fixtures/groups.yml +0 -86
  273. data/test/fixtures/groups_users.yml +0 -81
  274. data/test/fixtures/iformats.yml +0 -29
  275. data/test/fixtures/links.yml +0 -313
  276. data/test/fixtures/nodes.yml +0 -2592
  277. data/test/fixtures/relations.yml +0 -126
  278. data/test/fixtures/sites.yml +0 -58
  279. data/test/fixtures/template_contents.yml +0 -172
  280. data/test/fixtures/users.yml +0 -167
  281. data/test/fixtures/versions.yml +0 -1911
  282. data/test/fixtures/virtual_classes.yml +0 -87
  283. data/test/fixtures/zips.yml +0 -15
  284. data/test/functional/sessions_controller_test.rb +0 -73
@@ -1,6 +1,4 @@
1
- <label for="node_c_file"><%= _("document file") %></label>
2
- <div id="file" class='toggle_div'><%= link_to_remote(_("change"), :update=>'file_form', :url=>file_form_documents_path(:uuid => @uuid), :method => :get, :complete=>"['file', 'file_form'].each(Element.toggle);$('attachment#{@uuid}').click();") %></div>
3
- <div id="file_form" class='toggle_div' style='display:none;'></div>
1
+ <%= upload_field(:type => :onclick) %>
4
2
 
5
3
  <label for='node_c_content_type'><%= _('content type') %></label>
6
4
  <input id='node_c_content_type' type='text' name='node[c_content_type]' value='<%= @node.c_content_type %>'/><br/>
@@ -1,6 +1,4 @@
1
- <label for="node_c_file"><%= _("document file") %></label>
2
- <div id="file" class='toggle_div'><%= link_to_remote(_("change"), :update=>'file_form', :url=>file_form_documents_path(:uuid => @uuid), :method => :get, :complete=>"['file', 'file_form'].each(Element.toggle);$('attachment#{@uuid}').click();") %></div>
3
- <div id="file_form" class='toggle_div' style='display:none;'></div>
1
+ <%= upload_field(:type => :onclick) %>
4
2
 
5
3
  <%= @node.c_version_id == @node.v_id ? "<b id='original_caution'>#{_('you are editing the original')}</b>" : "" %>
6
4
 
@@ -3,7 +3,7 @@
3
3
  <td class="number" onclick="Zena.diff_select(this);"><%= tr.number %></td>
4
4
  <td class="box"><%= tr.lang %></td>
5
5
  <td class="actions"><%= version_actions(tr) %></td>
6
- <td class="sign"><%= tr.user.initials %></td>
6
+ <td class="sign"><%= tr.user.login %></td>
7
7
  <td class="date"><%= format_date(tr.created_at, 'age') %></td>
8
8
  <td class="comment"><%= tr.comment %></td>
9
9
  </tr>
@@ -13,10 +13,10 @@
13
13
  </div>
14
14
  <div class='validate'>
15
15
  <div>
16
- <input name="validate" type="submit" value="<%= _('validate') %>" />
16
+ <input name='validate' type='submit' value='<%= _('validate') %>' />
17
17
  </div>
18
18
  <div>
19
- <input name="save" onclick="return Zena.save('<%= save_text_node_path(:id => @node[:zip]) %>',this.form,false);" type="button" value="<%= _('save') %>" />
19
+ <input name='save' onclick="return Zena.save('<%= save_text_node_path(:id => @node[:zip]) %>',this.form,false);" type='button' value='<%= _('save') %>' />
20
20
  </div>
21
21
  <div><a href='#' onclick='uploader=window.open("<%= new_document_path(:parent_id=>@node[:zip])%>", "uploader", "location=1,width=400,height=300");uploader.opener = opener;return false;'><%= _('btn_add_document')%></a></div>
22
22
  <% if @node.can_publish? && !visitor.site.auto_publish? %><div><small><input type='checkbox' name='node[v_backup]' value='true'/> <%= _('bak') %></small> <small><input type='checkbox' name='node[v_status]' value='50'<%= params[:pub] ? " checked='checked'" : '' %>/> <%= _('pub') %></small></div><% end -%>
@@ -29,27 +29,3 @@
29
29
 
30
30
  </form>
31
31
  </div>
32
-
33
- <%#= css_edit %>
34
- <% javascript_tag do -%>
35
- var current_sel = $('<%= partial[0] %>_sel');
36
- var current_tab = $('<%= partial[0] %>_tab');
37
- Event.observe(window, 'resize', function() { Zena.resizeElement('node_v_text'); } );
38
- Event.observe(window, 'resize', function() { Zena.resizeElement('node_v_text'); } );
39
- function popup_loaded() {
40
- <% if params[:close] == 'true' %>
41
- opener.window.location.href = opener.window.location.href;
42
- window.close();
43
- <% else -%>
44
- Zena.resizeElement('node_v_text');
45
- <% end -%>
46
- }
47
-
48
- $('node_form').getElements().each(function(input, index) {
49
- new Form.Element.Observer(input, 3, function(element, value) {
50
- <%= "opener.Zena.editor_preview('#{preview_node_version_path(:node_id=>@node[:zip], :id=>(@node.v_number || 0), :escape => false)}',element,value);" %>
51
- });
52
- });
53
-
54
- <% end -%>
55
- <iframe id="UploadIFrame" name="UploadIFrame" src="about:blank"></iframe>
data/bin/zena CHANGED
@@ -1,10 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'rubygems'
3
3
  require 'zena/info'
4
+
5
+ if %w(--version -v).include? ARGV.first
6
+ puts "zena #{Zena::VERSION}"
7
+ exit(0)
8
+ end
9
+
4
10
  require 'rails/version'
5
11
  require 'rails_generator'
6
12
  require 'rails_generator/scripts/generate'
7
-
8
13
  template_path = File.join(Zena::ROOT, 'lib', 'zena', 'deploy', 'template.rb')
9
14
  args = ["-m", template_path]
10
15
  args << ARGV.first
@@ -0,0 +1,18 @@
1
+ == Presentation
2
+
3
+ Provides delayed jobs: long running tasks can be processed offline,
4
+ without halting the visitor's browser. If you enable sphinx, this is
5
+ a must-have once your site grows bigger and you have lots of deltas
6
+ between index rebuilds.
7
+
8
+ == Install
9
+
10
+ Drop the folder into the "bricks" folder and install the delayed_job gem:
11
+
12
+ # install delayed_job gem:
13
+ > sudo gem install delayed_job --source http://gemcutter.org
14
+
15
+ # if you want to use this with sphinx you also need
16
+ > sudo gem install ts-delayed-delta --source http://gemcutter.org
17
+
18
+ # enable brick in config/bricks.yml
@@ -0,0 +1,19 @@
1
+ class CreateDelayedJobsTable < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :delayed_jobs, :force => true do |table|
4
+ table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
5
+ table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
6
+ table.text :handler # YAML-encoded string of the object that will do work
7
+ table.text :last_error # reason for last failure (See Note below)
8
+ table.datetime :run_at # When to run. Could be Time.now for immediately, or sometime in the future.
9
+ table.datetime :locked_at # Set when a client is working on this object
10
+ table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
11
+ table.string :locked_by # Who is working on this object (if locked)
12
+ table.timestamps
13
+ end
14
+ end
15
+
16
+ def self.down
17
+ drop_table :delayed_jobs
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ require 'delayed_job'
2
+
3
+ # Run during initialization
4
+ Delayed::Job.destroy_failed_jobs = false
5
+ silence_warnings do
6
+ Delayed::Job.const_set("MAX_ATTEMPTS", 3)
7
+ Delayed::Job.const_set("MAX_RUN_TIME", 5.minutes)
8
+ end
@@ -0,0 +1,2 @@
1
+ require 'delayed_job'
2
+ require 'delayed/tasks'
@@ -19,7 +19,7 @@ module Bricks
19
19
 
20
20
  if opts[:output] == 'latex'
21
21
  "#{pre}#{content}#{post}"
22
- elsif ENABLE_MATH
22
+ elsif Zena::ENABLE_MATH
23
23
  # Create PNG image
24
24
  # 1. get image path
25
25
  math_id = Digest::SHA1.hexdigest(content)[0..4]
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Gaspard Bucher
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ == Presentation
2
+
3
+ Provides fulltext search through Sphinx.
4
+
5
+
6
+ == Install
7
+
8
+ Drop the folder into the "bricks" folder and install sphinx and thinking-sphinx:
9
+
10
+ # install sphinx
11
+ follow instructions: http://freelancing-god.github.com/ts/en/installing_sphinx.html
12
+
13
+ # install thinking sphinx gem:
14
+ > sudo gem install thinking-sphinx --source http://gemcutter.org
15
+
16
+ # if you want to use the delayed delta feature (you should on a big website), you also need
17
+ > sudo gem install ts-delayed-delta --source http://gemcutter.org
18
+
19
+ # enable brick in config/bricks.yml
@@ -0,0 +1,78 @@
1
+ require 'thinking_sphinx'
2
+
3
+ module Bricks
4
+ module Sphinx
5
+ module NodeClassMethods
6
+ include Zena::Acts::Secure
7
+ def search_records(query, opts = {})
8
+ with = opts[:with] || {}
9
+ with[:site_id] = current_site.id
10
+ if offset = opts[:offset]
11
+ limit = opts[:limit] || 20
12
+ ids = search_for_ids(query, :with => with, :limit => (offset + limit) * [limit,20].max)
13
+ return [] if ids.empty?
14
+ # 1. filter with secure
15
+ secure_ids = Zena::Db.fetch_ids("SELECT id FROM nodes WHERE id IN (#{ids.join(',')}) AND #{secure_scope('nodes')}")
16
+ # 2. reorder and apply offset
17
+ if offset_ids = (ids & secure_ids)[offset..(offset + limit - 1)]
18
+ # 3. populate
19
+ records = Node.find(:all, :conditions => {:id => offset_ids})
20
+ # 4. reorder
21
+ offset_ids.map {|id| records.detect {|r| r.id == id }}
22
+ else
23
+ []
24
+ end
25
+ else
26
+ if per_page = opts[:per_page]
27
+ page = opts[:page].to_i
28
+ page = 1 if page < 1
29
+ search_records(query, :offset => (page - 1) * per_page, :limit => per_page)
30
+ else
31
+ puts opts.inspect
32
+ search(query, opts).compact
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ module NodeSearch
39
+ def self.included(klass)
40
+ klass.extend NodeClassMethods
41
+
42
+ begin
43
+ require 'thinking_sphinx/deltas/delayed_delta'
44
+ ThinkingSphinx::Deltas::DelayedDelta
45
+ has_dd = Bricks::CONFIG['delayed_job']
46
+ rescue LoadError
47
+ has_dd = false
48
+ end
49
+
50
+ klass.class_eval do
51
+ define_index do
52
+ indexes name
53
+ indexes versions.title, :as => 'title'
54
+ indexes versions.text, :as => 'text'
55
+ indexes versions.summary, :as => 'summary'
56
+ indexes versions.dynamic_attributes.value, :as => 'attribute'
57
+ #indexes versions.dynamic_attributes.key, :as => 'key'
58
+
59
+ has site_id
60
+
61
+ where "versions.status >= #{Zena::Status[:pub]}"
62
+
63
+ set_property :field_weights => { :title => 5, :summary => 3, :text => 2, :attribute => 1 }
64
+ set_property :group_concat_max_len => 30000 # FIXME: articles can easily have a length of 17000 chars...
65
+ set_property :delta => (has_dd ? :delayed : true)
66
+ end
67
+ end
68
+
69
+ klass.before_save :set_delta
70
+ end
71
+
72
+ private
73
+ def set_delta
74
+ self.delta = true
75
+ end
76
+ end # NodeSearch
77
+ end # Sphinx
78
+ end # Bricks
@@ -0,0 +1,9 @@
1
+ class AddDeltaForSphinx < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :nodes, :delta, :boolean, :default => true, :null => false
4
+ end
5
+
6
+ def self.down
7
+ remove_column :nodes, :delta
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ require 'thinking_sphinx/deploy/capistrano'
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+
5
+ # FIXME: we should find a way to write a clean 'before' hook
6
+ # so that this is simply appeded to existing rules !!
7
+ task :before_update_code, :roles => [:app] do
8
+ thinking_sphinx.stop
9
+ end
10
+
11
+ task :after_update_code, :roles => [:app] do
12
+ symlink_sphinx_indexes
13
+ thinking_sphinx.configure
14
+ thinking_sphinx.start
15
+ end
16
+
17
+ task :symlink_sphinx_indexes, :roles => [:app] do
18
+ run "ln -nfs #{shared_path}/db/sphinx #{current_path}/db/sphinx"
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ test:
2
+ sql_range_step: 10000000
3
+
4
+ production:
5
+ enable_star: 1
6
+ min_infix_len: 2
7
+ pid_file: /var/zena/shared/tmp/searchd.pid
8
+ searchd_files: /var/zena/shared/db/sphinx
9
+
10
+ development:
11
+ enable_star: 1
12
+ min_infix_len: 2
@@ -0,0 +1,21 @@
1
+ require 'thinking_sphinx'
2
+ require 'thinking_sphinx/tasks'
3
+
4
+ begin
5
+ require 'thinking_sphinx/deltas/delayed_delta/tasks'
6
+ require 'thinking_sphinx/deltas/delayed_delta' # we need this line for the ts:dd job runner
7
+ rescue LoadError
8
+ # no delayed_delta
9
+ end
10
+
11
+ namespace :sphinx do
12
+
13
+ desc "Create a default configuration file"
14
+ task :config do
15
+ if File.exist?("#{RAILS_ROOT}/config/sphinx.yml")
16
+ puts "#{RAILS_ROOT}/config/sphinx.yml exists, not copying"
17
+ else
18
+ FileUtils.cp(File.join(File.dirname(__FILE__), 'sphinx.yml'), "#{RAILS_ROOT}/config/sphinx.yml")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ if errors = Bricks.runtime_requirement_errors('sphinx')
2
+ Node.logger.warn "## search might not work: #{errors.join(', ')}"
3
+ puts "## search might not work: #{errors.join(', ')}"
4
+ end
5
+
6
+ class Node
7
+ include Bricks::Sphinx::NodeSearch
8
+ end
@@ -2,7 +2,9 @@ module Bricks
2
2
  module Tags
3
3
  class StringHash
4
4
  include RubyLess::SafeClass
5
- safe_method [:[], String] => {:class => String, :nil => true}
5
+ safe_context [:[], String] => String
6
+ safe_method :keys => [String]
7
+ undef_method(:safe_read) # FIXME: use 'disable_safe_read' when new rubyless gem is published
6
8
  end
7
9
 
8
10
  module HasTags
@@ -15,8 +17,8 @@ module Bricks
15
17
  module TriggerClassMethod
16
18
  def has_tags
17
19
  after_save :update_tags
18
- zafu_context :tags => ["Link"]
19
- safe_method :tag_list => String, :tag => String, :tagged => StringHash
20
+ safe_context :tags => ['Link']
21
+ safe_method :tag_list => String, :tag => String, :tagged => StringHash, :tag_names => [String]
20
22
 
21
23
  class_eval <<-END
22
24
  include Bricks::Tags::InstanceMethods
@@ -25,4 +25,16 @@ tagged_query:
25
25
 
26
26
  images_tagged_blue:
27
27
  src: "<r:images where='tag=\"blue\"' in='site' do='each' join=', ' do='[name]'/>"
28
- res: "bird"
28
+ res: "bird"
29
+
30
+ tagged_keys_rubyless:
31
+ context:
32
+ node: 'status'
33
+ src: "<r:tagged do='keys'><r:each join=', ' do='show'/></r:tagged>"
34
+ res: "sky, blue"
35
+
36
+ tag_names:
37
+ context:
38
+ node: 'status'
39
+ src: "<r:tag_names><r:each join=', ' do='show'/></r:tagged>"
40
+ res: "sky, blue"
@@ -0,0 +1,35 @@
1
+ test:
2
+ tags: ON
3
+ captcha: ON
4
+ sphinx: OFF
5
+ delayed_job: OFF
6
+
7
+ development:
8
+ tags: ON
9
+ captcha: ON
10
+ sphinx:
11
+ switch: OFF
12
+ activate_if:
13
+ gem: 'thinking_sphinx'
14
+ adapter: 'mysql,postgresql'
15
+ run_if:
16
+ file: 'log/searchd.development.pid'
17
+ delayed_job:
18
+ switch: OFF
19
+ activate_if:
20
+ gem: 'delayed_job'
21
+
22
+ production:
23
+ tags: ON
24
+ captcha: ON
25
+ sphinx:
26
+ switch: ON
27
+ activate_if:
28
+ gem: 'thinking_sphinx'
29
+ adapter: 'mysql,postgresql'
30
+ run_if:
31
+ file: 'log/searchd.production.pid'
32
+ delayed_job:
33
+ switch: ON
34
+ activate_if:
35
+ gem: 'delayed_job'
@@ -1,5 +1,5 @@
1
1
  set :db_name, "zena" # If you change this: no dots in this name !
2
- set :server_ip, nil # FIXME: set this to your remote server IP in the form: "215.0.0.1"
2
+ set :server_ip, 3333 # FIXME: set this to your remote server IP in the form: "215.0.0.1"
3
3
  set :mongrel_port, "8000"
4
4
  set :mongrel_count, "3"
5
5
  set :db_password, nil # FIXME: set password (can be anything).
@@ -25,6 +25,13 @@ if self[:server_ip]
25
25
  role :db, "#{ssh_user}@#{server_ip}", :primary => true
26
26
 
27
27
  #================= END ADVANCED SETTINGS ==========#
28
+ # We need to set RAILS_ROOT and RAILS_ENV to know which bricks we need to load, activate
29
+ if !defined?(::RAILS_ROOT)
30
+ ::RAILS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
31
+ end
32
+ if !defined?(::RAILS_ENV)
33
+ ::RAILS_ENV = 'production'
34
+ end
28
35
  require 'zena/deploy'
29
36
 
30
37
  else