zena 0.15.2 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/CREDITS +27 -0
- data/Capfile +3 -0
- data/DEVELOPERS +46 -0
- data/History.txt +15 -0
- data/MIT-LICENSE +19 -0
- data/Rakefile +44 -0
- data/TODO +24 -0
- data/TODO_ZENA_1_0 +23 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/documents_controller.rb +22 -56
- data/app/controllers/nodes_controller.rb +42 -27
- data/app/controllers/pings_controller.rb +19 -0
- data/app/controllers/relations_controller.rb +5 -1
- data/app/controllers/sites_controller.rb +1 -46
- data/app/controllers/user_sessions_controller.rb +47 -0
- data/app/controllers/users_controller.rb +1 -0
- data/app/controllers/versions_controller.rb +25 -7
- data/app/controllers/virtual_classes_controller.rb +1 -1
- data/app/helpers/application_helper.rb +1 -1
- data/app/models/comment.rb +2 -1
- data/app/models/contact_content.rb +2 -2
- data/app/models/data_entry.rb +5 -6
- data/app/models/document.rb +14 -10
- data/app/models/document_content.rb +4 -6
- data/app/models/iformat.rb +2 -2
- data/app/models/image_content.rb +6 -9
- data/app/models/node.rb +106 -164
- data/app/models/page.rb +0 -20
- data/app/models/site.rb +42 -12
- data/app/models/template.rb +3 -8
- data/app/models/template_content.rb +2 -0
- data/app/models/text_document.rb +13 -8
- data/app/models/user.rb +47 -100
- data/app/models/user_session.rb +4 -0
- data/app/models/version.rb +1 -1
- data/app/views/comments/create.rjs +3 -3
- data/app/views/comments/edit.rjs +1 -1
- data/app/views/comments/update.rjs +1 -1
- data/app/views/nodes/_import_results.rhtml +1 -1
- data/app/views/nodes/create.rjs +3 -3
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -2
- data/app/views/templates/document_create_tabs/_import.rhtml +7 -2
- data/app/views/templates/edit_tabs/_document.rhtml +1 -3
- data/app/views/templates/edit_tabs/_image.rhtml +1 -3
- data/app/views/versions/_tr.rhtml +1 -1
- data/app/views/versions/edit.rhtml +2 -26
- data/bin/zena +6 -1
- data/bricks/delayed_job/README +18 -0
- data/bricks/delayed_job/migrate/20091104191643_create_delayed_jobs_table.rb +19 -0
- data/bricks/delayed_job/misc/init.rb +8 -0
- data/bricks/delayed_job/misc/tasks.rb +2 -0
- data/bricks/math/patch/application_helper.rb +1 -1
- data/bricks/sphinx/MIT-LICENSE +19 -0
- data/bricks/sphinx/README +19 -0
- data/bricks/sphinx/lib/use_sphinx.rb +78 -0
- data/bricks/sphinx/migrate/20091102171258_add_delta_for_sphinx.rb +9 -0
- data/bricks/sphinx/misc/deploy.rb +20 -0
- data/bricks/sphinx/misc/sphinx.yml +12 -0
- data/bricks/sphinx/misc/tasks.rb +21 -0
- data/bricks/sphinx/patch/node.rb +8 -0
- data/bricks/tags/lib/has_tags.rb +5 -3
- data/bricks/tags/test/zafu/tags.yml +13 -1
- data/config/bricks.yml +35 -0
- data/config/deploy.rb +8 -1
- data/config/environment.rb +1 -1
- data/config/environments/production.rb +1 -1
- data/config/gems.yml +28 -5
- data/config/sphinx.yml +12 -0
- data/db/init/base/skins/default/Node-+popupLayout.zafu +1 -16
- data/db/migrate/20091026161708_add_persistence_token.rb +13 -0
- data/db/migrate/20091101184952_add_session_table.rb +16 -0
- data/db/migrate/20091123175137_add_single_access_token.rb +9 -0
- data/db/migrate/20091124161608_rebuild_fullpath.rb +11 -0
- data/db/schema.rb +21 -8
- data/doc/README_FOR_APP +24 -0
- data/doc/fixtures.graffle +19568 -0
- data/doc/fixtures.pdf +0 -0
- data/doc/template/LICENSE +184 -0
- data/doc/template/README +37 -0
- data/doc/template/allison.css +283 -0
- data/doc/template/allison.js +307 -0
- data/doc/template/allison.rb +260 -0
- data/doc/template/cache/BODY +588 -0
- data/doc/template/cache/CLASS_INDEX +4 -0
- data/doc/template/cache/CLASS_PAGE +1 -0
- data/doc/template/cache/FILE_INDEX +4 -0
- data/doc/template/cache/FILE_PAGE +1 -0
- data/doc/template/cache/FONTS +1 -0
- data/doc/template/cache/FR_INDEX_BODY +1 -0
- data/doc/template/cache/IMGPATH +1 -0
- data/doc/template/cache/INDEX +1 -0
- data/doc/template/cache/JAVASCRIPT +307 -0
- data/doc/template/cache/METHOD_INDEX +4 -0
- data/doc/template/cache/METHOD_LIST +1 -0
- data/doc/template/cache/SRC_PAGE +1 -0
- data/doc/template/cache/STYLE +283 -0
- data/doc/template/cache/URL +1 -0
- data/doc/zafu_changes.yml +29 -0
- data/lib/base_additions.rb +1 -1
- data/lib/bricks.rb +9 -0
- data/lib/bricks/loader.rb +86 -0
- data/lib/bricks/requirements_validation.rb +71 -0
- data/lib/tasks/zena.rake +42 -4
- data/lib/zafu/action.rb +285 -0
- data/lib/zafu/ajax.rb +93 -0
- data/lib/zafu/attributes.rb +117 -0
- data/lib/zafu/calendar.rb +159 -0
- data/lib/zafu/context.rb +330 -0
- data/lib/zafu/core/html.rb +102 -0
- data/lib/zafu/core/move_to_parser.rb +167 -0
- data/lib/zafu/dates.rb +58 -0
- data/lib/zafu/display.rb +502 -0
- data/lib/zafu/eval.rb +66 -0
- data/lib/zafu/experimental.rb +66 -0
- data/lib/zafu/i18n.rb +64 -0
- data/lib/zafu/meta.rb +25 -0
- data/lib/zafu/refactor.rb +73 -0
- data/lib/zafu/support/context.rb +265 -0
- data/lib/zafu/support/dom.rb +145 -0
- data/lib/zafu/support/erb.rb +62 -0
- data/lib/zafu/support/flow.rb +401 -0
- data/lib/zafu/support/forms.rb +461 -0
- data/lib/zafu/support/links.rb +306 -0
- data/lib/zafu_parser.rb +26 -2
- data/lib/zena.rb +34 -15
- data/lib/zena/acts/multiversion.rb +2 -2
- data/lib/zena/acts/secure.rb +41 -30
- data/lib/zena/app.rb +7 -10
- data/lib/zena/controller/test_case.rb +12 -7
- data/lib/zena/crypto_provider/initial.rb +15 -0
- data/lib/zena/db.rb +6 -1
- data/lib/zena/deploy.rb +34 -6
- data/lib/zena/deploy/logrotate_app.rhtml +9 -0
- data/lib/zena/deploy/logrotate_host.rhtml +34 -0
- data/lib/zena/deploy/template.rb +1 -9
- data/lib/zena/foxy_parser.rb +1 -1
- data/lib/zena/info.rb +3 -1
- data/lib/zena/migrator.rb +1 -1
- data/lib/zena/parser.rb +12 -4
- data/lib/zena/parser/zazen_rules.rb +6 -6
- data/lib/zena/parser/zena_rules.rb +1 -7
- data/lib/zena/routes.rb +5 -5
- data/lib/zena/test_controller.rb +7 -2
- data/lib/zena/unit/test_case.rb +6 -8
- data/lib/zena/use/ajax.rb +10 -10
- data/lib/zena/use/authlogic.rb +93 -0
- data/lib/zena/use/dyn_attributes.rb +5 -0
- data/lib/zena/use/html_tags.rb +16 -34
- data/lib/zena/use/i18n.rb +4 -1
- data/lib/zena/use/node_query_finders.rb +8 -4
- data/lib/zena/use/refactor.rb +8 -20
- data/lib/zena/use/relations.rb +1 -0
- data/lib/zena/use/rendering.rb +4 -2
- data/lib/zena/use/search.rb +52 -0
- data/lib/zena/use/test_helper.rb +27 -28
- data/lib/zena/use/upload.rb +188 -0
- data/lib/zena/use/urls.rb +16 -14
- data/lib/zena/use/zafu.rb +16 -63
- data/lib/zena/use/zazen.rb +8 -8
- data/lib/zena/view/test_case.rb +8 -4
- data/locale/en/LC_MESSAGES/zena.mo +0 -0
- data/locale/en/zena.po +3 -3
- data/public/.htaccess +40 -0
- data/public/javascripts/upload-progress.js +17 -8
- data/public/javascripts/zena.js +8 -2
- data/public/stylesheets/popup.css +1 -0
- data/script/about +3 -0
- data/script/apache_logging +25 -0
- data/script/breakpointer +3 -0
- data/script/console +3 -0
- data/script/dbconsole +3 -0
- data/script/destroy +3 -0
- data/script/generate +3 -0
- data/script/performance/benchmarker +3 -0
- data/script/performance/profiler +3 -0
- data/script/plugin +3 -0
- data/script/process/inspector +3 -0
- data/script/process/reaper +3 -0
- data/script/process/spawner +3 -0
- data/script/runner +3 -0
- data/script/server +3 -0
- data/script/set_revision +29 -0
- data/spec/controllers/versions_controller_spec.rb +11 -0
- data/test/fixtures/files/Node-test.zafu +1 -1
- data/test/functional/nodes_controller_test.rb +25 -0
- data/test/functional/pings_controller_test.rb +8 -0
- data/test/functional/user_sessions_controller_test.rb +59 -0
- data/test/functional/users_controller_test.rb +81 -19
- data/test/helpers/node_query/filters.yml +5 -0
- data/test/helpers/node_query_test.rb +3 -3
- data/test/integration/multiple_hosts_test.rb +1 -1
- data/test/integration/navigation_test.rb +1 -1
- data/test/sites/complex/users.yml +1 -1
- data/test/sites/ocean/users.yml +3 -3
- data/test/sites/zena/users.yml +5 -4
- data/test/test_zena.rb +38 -38
- data/test/unit/cached_page_test.rb +2 -2
- data/test/unit/comment_test.rb +0 -1
- data/test/unit/document_test.rb +23 -11
- data/test/unit/helpers/ping_helper_test.rb +4 -0
- data/test/unit/multiversion_test.rb +24 -16
- data/test/unit/node_test.rb +32 -93
- data/test/unit/note_test.rb +9 -0
- data/test/unit/page_test.rb +2 -2
- data/test/unit/secure_test.rb +2 -12
- data/test/unit/site_test.rb +43 -24
- data/test/unit/template_test.rb +45 -3
- data/test/unit/text_document_test.rb +4 -3
- data/test/unit/user_test.rb +13 -33
- data/test/unit/zena/db_test.rb +8 -0
- data/test/unit/zena/parser/zazen.yml +4 -4
- data/test/unit/zena/use/dates_view_methods_test.rb +2 -1
- data/test/unit/zena/use/html_tags_test.rb +12 -4
- data/test/unit/zena/use/refactor_test.rb +4 -3
- data/test/unit/zena/use/rendering_test.rb +1 -0
- data/test/unit/zena/use/upload_test.rb +76 -0
- data/test/unit/zena/use/urls_test.rb +4 -0
- data/test/unit/zena/use/zafu_test.rb +8 -0
- data/test/unit/zena/workflow/status_version_test.rb +6 -0
- data/test/unit/zena/zena_tags/ajax.yml +4 -4
- data/test/unit/zena/zena_tags/basic.yml +21 -10
- data/test/unit/zena/zena_tags/relations.yml +0 -6
- data/test/unit/zena/zena_tags/rubyless.yml +35 -0
- data/test/unit/zena/zena_tags/zazen.yml +4 -4
- data/test/unit/zena/zena_tags_test.rb +36 -4
- data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +1 -1
- data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +2 -3
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/catch_exception.rb +39 -0
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +102 -58
- data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/stdin_dialog.rb +14 -0
- data/vendor/TextMate/Zena.tmbundle/info.plist +2 -0
- data/zena.gemspec +2085 -0
- metadata +265 -90
- data/app/controllers/sessions_controller.rb +0 -41
- data/app/views/sites/zena_up.html.erb +0 -11
- data/config/database.yml +0 -40
- data/db/production.sqlite3 +0 -0
- data/lib/bricks/patcher.rb +0 -68
- data/lib/zena/parser/zena_tags.rb +0 -3562
- data/lib/zena/use/authentification.rb +0 -120
- data/public/images/ext/contact_pv.png +0 -0
- data/public/images/ext/other_pv.png +0 -0
- data/public/images/ext/page_pv.png +0 -0
- data/public/images/ext/page_tiny.png +0 -0
- data/public/images/ext/pdf_pv.png +0 -0
- data/public/images/ext/post_pv.png +0 -0
- data/public/images/ext/post_tiny.png +0 -0
- data/public/images/ext/project_pv.png +0 -0
- data/public/images/ext/project_tiny.png +0 -0
- data/public/images/ext/tag_pv.png +0 -0
- data/public/images/ext/zip_pv.png +0 -0
- data/tasks/ann.rake +0 -80
- data/tasks/bones.rake +0 -20
- data/tasks/gem.rake +0 -201
- data/tasks/git.rake +0 -40
- data/tasks/notes.rake +0 -27
- data/tasks/post_load.rake +0 -34
- data/tasks/rdoc.rake +0 -51
- data/tasks/rubyforge.rake +0 -55
- data/tasks/setup.rb +0 -292
- data/tasks/spec.rake +0 -54
- data/tasks/svn.rake +0 -47
- data/tasks/test.rake +0 -40
- data/tasks/zentest.rake +0 -36
- data/test/fixtures/comments.yml +0 -126
- data/test/fixtures/contact_contents.yml +0 -132
- data/test/fixtures/data_entries.yml +0 -65
- data/test/fixtures/discussions.yml +0 -48
- data/test/fixtures/document_contents.yml +0 -108
- data/test/fixtures/dyn_attributes.yml +0 -66
- data/test/fixtures/groups.yml +0 -86
- data/test/fixtures/groups_users.yml +0 -81
- data/test/fixtures/iformats.yml +0 -29
- data/test/fixtures/links.yml +0 -313
- data/test/fixtures/nodes.yml +0 -2592
- data/test/fixtures/relations.yml +0 -126
- data/test/fixtures/sites.yml +0 -58
- data/test/fixtures/template_contents.yml +0 -172
- data/test/fixtures/users.yml +0 -167
- data/test/fixtures/versions.yml +0 -1911
- data/test/fixtures/virtual_classes.yml +0 -87
- data/test/fixtures/zips.yml +0 -15
- data/test/functional/sessions_controller_test.rb +0 -73
data/lib/zena/use/i18n.rb
CHANGED
@@ -136,7 +136,10 @@ module Zena
|
|
136
136
|
include Common
|
137
137
|
|
138
138
|
def self.included(base)
|
139
|
-
|
139
|
+
FastGettext.add_text_domain 'zena', :path => "#{Zena::ROOT}/locale"
|
140
|
+
base.prepend_before_filter { FastGettext.text_domain = 'zena' }
|
141
|
+
base.before_filter :set_lang, :check_lang
|
142
|
+
base.after_filter :set_encoding
|
140
143
|
end
|
141
144
|
|
142
145
|
# Choose best language to display content.
|
@@ -193,7 +193,7 @@ class NodeQuery < QueryBuilder
|
|
193
193
|
end
|
194
194
|
|
195
195
|
def map_literal(value, env = :sql)
|
196
|
-
if value =~ /(.*?)\[(visitor|param):(\w+)\](.*)/
|
196
|
+
if value =~ /(.*?)\[(visitor|param|node):(\w+)\](.*)/
|
197
197
|
val_start = $1 == '' ? '' : "#{$1.inspect} +"
|
198
198
|
val_end = $4 == '' ? '' : "+ #{$4.inspect}"
|
199
199
|
case $2
|
@@ -201,6 +201,9 @@ class NodeQuery < QueryBuilder
|
|
201
201
|
value = env == :sql ? insert_bind("#{val_start}Node.zafu_attribute(visitor.contact, #{$3.inspect})#{val_end}") : nil
|
202
202
|
when 'param'
|
203
203
|
value = env == :sql ? insert_bind("#{val_start}params[:#{$3}].to_s#{val_end}") : "params[:#{$3}]"
|
204
|
+
when 'node'
|
205
|
+
@uses_node_name = true
|
206
|
+
value = env == :sql ? insert_bind("#{val_start}#{@node_name}.safe_read(#{$3.inspect}).to_s#{val_end}") : "#{@node_name}.safe_read(#{$3.inspect})"
|
204
207
|
end
|
205
208
|
else
|
206
209
|
value = env == :sql ? quote(value) : nil
|
@@ -470,11 +473,12 @@ module Zena
|
|
470
473
|
|
471
474
|
# Find related nodes.
|
472
475
|
# See Node#build_find for details on the options available.
|
473
|
-
|
476
|
+
# TODO: replace with rubyless translate ? Is this thing really used anyway ?
|
477
|
+
def find(count, rel, opts = {})
|
474
478
|
rel = [rel] if rel.kind_of?(String)
|
475
479
|
|
476
|
-
if rel.size == 1 && self.class
|
477
|
-
self.send(
|
480
|
+
if !opts[:skip_rubyless] && rel.size == 1 && type = RubyLess::SafeClass.safe_method_type_for(self.class, [rel.first])
|
481
|
+
self.send(type[:method])
|
478
482
|
else
|
479
483
|
query = Node.build_find(count, rel, :node_name => 'self')
|
480
484
|
if query.valid?
|
data/lib/zena/use/refactor.rb
CHANGED
@@ -1,30 +1,17 @@
|
|
1
1
|
module Zena
|
2
2
|
module Use
|
3
3
|
module Refactor
|
4
|
-
module Common
|
5
4
|
|
5
|
+
module Common
|
6
6
|
# TODO: test
|
7
7
|
def lang
|
8
|
-
visitor.lang
|
8
|
+
@lang ||= visitor.lang
|
9
9
|
end
|
10
10
|
end # Common
|
11
11
|
|
12
12
|
module ControllerMethods
|
13
13
|
include Common
|
14
14
|
|
15
|
-
# TODO: test
|
16
|
-
def visitor
|
17
|
-
@visitor ||= returning(User.make_visitor(:host => request.host, :id => session[:user])) do |user|
|
18
|
-
if session[:user] != user[:id]
|
19
|
-
# changed user (login/logout)
|
20
|
-
session[:user] = user[:id]
|
21
|
-
end
|
22
|
-
if user.is_anon?
|
23
|
-
user.ip = request.headers['REMOTE_ADDR']
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
15
|
# Read the parameters and add errors to the object if it is considered spam. Save it otherwize.
|
29
16
|
def save_if_not_spam(obj, params)
|
30
17
|
# do nothing (overwritten by plugins like zena_captcha)
|
@@ -34,9 +21,8 @@ module Zena
|
|
34
21
|
end # ControllerMethods
|
35
22
|
|
36
23
|
module ViewMethods
|
37
|
-
include Common
|
38
24
|
|
39
|
-
|
25
|
+
include Common
|
40
26
|
|
41
27
|
# Quote for html values (input tag, alt attribute, etc)
|
42
28
|
def fquote(text)
|
@@ -175,7 +161,7 @@ ENDTXT
|
|
175
161
|
obj = opts[:node] || @node
|
176
162
|
trad_list = []
|
177
163
|
(obj.traductions || []).each do |ed|
|
178
|
-
trad_list << "<span#{ ed.lang == lang ? " class='current'" : ''}>" + link_to( _(ed[:lang]), zen_path(obj,:lang=>ed[:lang])) + "</span>"
|
164
|
+
trad_list << "<span#{ ed.lang == visitor.lang ? " class='current'" : ''}>" + link_to( _(ed[:lang]), zen_path(obj,:lang=>ed[:lang])) + "</span>"
|
179
165
|
end
|
180
166
|
trad_list
|
181
167
|
end
|
@@ -190,11 +176,13 @@ ENDTXT
|
|
190
176
|
|
191
177
|
# This lets helpers render partials
|
192
178
|
# TODO: make sure this is the best way to handle this problem.
|
179
|
+
|
193
180
|
def render_to_string(*args)
|
194
|
-
|
181
|
+
controller ||= begin
|
195
182
|
# ==> this means render_to_string uses a view with everything ApplicationController has...
|
196
183
|
ApplicationController.new.instance_eval do
|
197
184
|
class << self
|
185
|
+
public :render, :render_to_string
|
198
186
|
attr_accessor :request, :response, :params
|
199
187
|
end
|
200
188
|
|
@@ -209,7 +197,7 @@ ENDTXT
|
|
209
197
|
end
|
210
198
|
end
|
211
199
|
|
212
|
-
|
200
|
+
controller.render(*args)
|
213
201
|
end
|
214
202
|
|
215
203
|
end # ViewMethods
|
data/lib/zena/use/relations.rb
CHANGED
data/lib/zena/use/rendering.rb
CHANGED
@@ -13,6 +13,7 @@ module Zena
|
|
13
13
|
module ControllerMethods
|
14
14
|
def self.included(base)
|
15
15
|
base.send(:helper_attr, :js_data)
|
16
|
+
base.send(:layout, false)
|
16
17
|
end
|
17
18
|
|
18
19
|
def js_data
|
@@ -94,11 +95,11 @@ module Zena
|
|
94
95
|
params.delete(:mode)
|
95
96
|
|
96
97
|
if opts[:format] != 'html'
|
97
|
-
content_type = (EXT_TO_TYPE[opts[:format]] || ['application/octet-stream'])[0]
|
98
|
+
content_type = (Zena::EXT_TO_TYPE[opts[:format]] || ['application/octet-stream'])[0]
|
98
99
|
template_path = template_url(opts)
|
99
100
|
data = render_to_string(:file => template_path, :layout=>false)
|
100
101
|
# TODO: use plugins...
|
101
|
-
if opts[:format] == 'pdf' && ((ENABLE_LATEX && data =~ /\A% (latex)\n/) || (ENABLE_FOP && data =~ /\A<\?(xml)/))
|
102
|
+
if opts[:format] == 'pdf' && ((Zena::ENABLE_LATEX && data =~ /\A% (latex)\n/) || (Zena::ENABLE_FOP && data =~ /\A<\?(xml)/))
|
102
103
|
rendering_egine = $1 == 'xml' ? 'fop' : $1
|
103
104
|
# 1. find cached PDF. If found, send data.
|
104
105
|
if @node[:user_id] == visitor[:id]
|
@@ -252,6 +253,7 @@ module Zena
|
|
252
253
|
|
253
254
|
# TODO: test
|
254
255
|
def popup_layout
|
256
|
+
js_data << "var is_editor = true;"
|
255
257
|
template_url(:mode=>'+popupLayout')
|
256
258
|
end
|
257
259
|
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Zena
|
2
|
+
module Use
|
3
|
+
module Search
|
4
|
+
module NodeClassMethods
|
5
|
+
# Return a hash to do a fulltext query.
|
6
|
+
def match_query(query, opts={})
|
7
|
+
node = opts.delete(:node)
|
8
|
+
if query == '.' && node
|
9
|
+
return opts.merge(
|
10
|
+
:conditions => ["parent_id = ?",node[:id]],
|
11
|
+
:order => 'name ASC' )
|
12
|
+
elsif !query.blank?
|
13
|
+
if Zena::Db.adapter == 'mysql' && RAILS_ENV != 'test'
|
14
|
+
match = sanitize_sql(["MATCH (vs.title,vs.text,vs.summary) AGAINST (?) OR nodes.name LIKE ?", query, "#{opts[:name_query] || query.url_name}%"])
|
15
|
+
select = sanitize_sql(["nodes.*, MATCH (vs.title,vs.text,vs.summary) AGAINST (?) + (5 * (nodes.name LIKE ?)) AS score", query, "#{query}%"])
|
16
|
+
else
|
17
|
+
match = sanitize_sql(["nodes.name LIKE ?", "#{query}%"])
|
18
|
+
select = "nodes.*, #{match} AS score"
|
19
|
+
end
|
20
|
+
|
21
|
+
return opts.merge(
|
22
|
+
:select => select,
|
23
|
+
:joins => "INNER JOIN versions AS vs ON vs.node_id = nodes.id AND vs.status >= #{Zena::Status[:pub]}",
|
24
|
+
:conditions => match,
|
25
|
+
:group => "nodes.id",
|
26
|
+
:order => "score DESC, zip ASC")
|
27
|
+
else
|
28
|
+
# error
|
29
|
+
return opts.merge(:conditions => '0')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def search_records(query, opts={})
|
34
|
+
with = opts[:with] || {}
|
35
|
+
with[:site_id] = current_site.id
|
36
|
+
if offset = opts[:offset]
|
37
|
+
limit = opts[:limit] || 20
|
38
|
+
Node.find(:all, match_query(query).merge(:offset => offset, :limit => limit))
|
39
|
+
else
|
40
|
+
if per_page = opts[:per_page]
|
41
|
+
page = opts[:page].to_i
|
42
|
+
page = 1 if page < 1
|
43
|
+
search_records(query, :offset => (page - 1) * per_page, :limit => per_page)
|
44
|
+
else
|
45
|
+
Node.find(:all, match_query(query, opts))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end # NodeClassMethods
|
50
|
+
end # Search
|
51
|
+
end # Use
|
52
|
+
end # Zena
|
data/lib/zena/use/test_helper.rb
CHANGED
@@ -1,26 +1,30 @@
|
|
1
|
+
require "authlogic/test_case"
|
1
2
|
require 'hpricot'
|
3
|
+
|
2
4
|
module Zena
|
3
5
|
module Use
|
4
6
|
module TestHelper
|
5
|
-
|
6
|
-
def test_site(site_name)
|
7
|
-
$_test_site = site_name
|
8
|
-
end
|
7
|
+
include Zena::Use::Upload::UploadedFile
|
9
8
|
|
10
9
|
# Set visitor for unit testing
|
11
|
-
def login(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
def login(fixture)
|
11
|
+
user = users(fixture)
|
12
|
+
Thread.current[:visitor] = user = users(fixture)
|
13
|
+
user.ip = '10.0.0.44'
|
14
|
+
$_test_site = user.site.name
|
15
|
+
::I18n.locale = user.lang
|
16
|
+
end
|
17
|
+
|
18
|
+
# Show object's errors
|
19
|
+
def err(obj)
|
20
|
+
obj.errors.each_error do |er,msg|
|
21
|
+
puts "[#{er}] #{msg}"
|
19
22
|
end
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
# Set the current site used for testing (mostly to generate ids)
|
26
|
+
def test_site(site_name)
|
27
|
+
$_test_site = site_name
|
24
28
|
end
|
25
29
|
|
26
30
|
def set_date(node_syms, opts = {})
|
@@ -83,7 +87,7 @@ module Zena
|
|
83
87
|
end
|
84
88
|
|
85
89
|
# taken from http://manuals.rubyonrails.com/read/chapter/28#page237 with some modifications
|
86
|
-
def
|
90
|
+
def uploaded_fixture(fname, content_type="application/octet-stream", filename=nil)
|
87
91
|
path = File.join(FILE_FIXTURES_PATH, fname)
|
88
92
|
filename ||= File.basename(path)
|
89
93
|
# simulate small files with StringIO
|
@@ -94,42 +98,37 @@ module Zena
|
|
94
98
|
t = Tempfile.new(fname)
|
95
99
|
FileUtils.copy_file(path, t.path)
|
96
100
|
end
|
97
|
-
(
|
98
|
-
alias local_path path if defined?(:path)
|
99
|
-
define_method(:original_filename) { filename }
|
100
|
-
define_method(:content_type) { content_type }
|
101
|
-
end
|
102
|
-
return t
|
101
|
+
uploaded_file(t, filename, content_type)
|
103
102
|
end
|
104
103
|
|
105
104
|
# JPEG helper
|
106
105
|
def uploaded_jpg(fname, filename=nil)
|
107
|
-
|
106
|
+
uploaded_fixture(fname, 'image/jpeg', filename)
|
108
107
|
end
|
109
108
|
|
110
109
|
# PDF helper
|
111
110
|
def uploaded_pdf(fname, filename=nil)
|
112
|
-
|
111
|
+
uploaded_fixture(fname, 'application/pdf', filename)
|
113
112
|
end
|
114
113
|
|
115
114
|
# TEXT helper
|
116
115
|
def uploaded_text(fname, filename=nil)
|
117
|
-
|
116
|
+
uploaded_fixture(fname, 'text/plain', filename)
|
118
117
|
end
|
119
118
|
|
120
119
|
# PNG helper
|
121
120
|
def uploaded_png(fname, filename=nil)
|
122
|
-
|
121
|
+
uploaded_fixture(fname, 'image/png', filename)
|
123
122
|
end
|
124
123
|
|
125
124
|
# TGZ helper
|
126
125
|
def uploaded_archive(fname, filename=nil)
|
127
|
-
|
126
|
+
uploaded_fixture(fname, 'application/x-gzip', filename)
|
128
127
|
end
|
129
128
|
|
130
129
|
# ZIP helper
|
131
130
|
def uploaded_zip(fname, filename=nil)
|
132
|
-
|
131
|
+
uploaded_fixture(fname, 'application/zip', filename)
|
133
132
|
end
|
134
133
|
|
135
134
|
def file_path(filename, mode = 'full', content_id = nil)
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uuidtools'
|
4
|
+
|
5
|
+
module Zena
|
6
|
+
module Use
|
7
|
+
module Upload
|
8
|
+
def self.has_network?
|
9
|
+
response = nil
|
10
|
+
Net::HTTP.new('example.com', '80').start do |http|
|
11
|
+
response = http.head('/')
|
12
|
+
end
|
13
|
+
response.kind_of? Net::HTTPSuccess
|
14
|
+
rescue
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
module UploadedFile
|
19
|
+
protected
|
20
|
+
def uploaded_file(file, filename = nil, content_type = nil)
|
21
|
+
(class << file; self; end;).class_eval do
|
22
|
+
alias local_path path if respond_to?(:path) # FIXME: do we need this ?
|
23
|
+
define_method(:original_filename) { filename }
|
24
|
+
define_method(:content_type) { content_type }
|
25
|
+
end
|
26
|
+
file
|
27
|
+
end
|
28
|
+
end # UploadedFile
|
29
|
+
|
30
|
+
module ControllerMethods
|
31
|
+
include UploadedFile
|
32
|
+
protected
|
33
|
+
include ActionView::Helpers::NumberHelper # number_to_human_size
|
34
|
+
def get_attachment
|
35
|
+
att, error = nil, nil
|
36
|
+
if !params['attachment_url'].blank?
|
37
|
+
att, error = fetch_uri(params['attachment_url'])
|
38
|
+
else
|
39
|
+
att = params['attachment']
|
40
|
+
end
|
41
|
+
yield(att, error) if block_given?
|
42
|
+
[att, error]
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def fetch_uri(uri_str, max_file_size = 10)
|
47
|
+
max_file_size = max_file_size * 1024 * 1024 # Mo
|
48
|
+
|
49
|
+
# first check head
|
50
|
+
response, error = fetch_response(uri_str, :head)
|
51
|
+
return [nil, error] unless response
|
52
|
+
if response['Content-Length'].nil?
|
53
|
+
return [nil, 'unknown size: cannot fetch url']
|
54
|
+
elsif response['Content-Length'].to_i > max_file_size
|
55
|
+
return [nil, 'size (%s) too big to fetch url' % number_to_human_size(response['Content-Length'].to_i)]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Size is ok, get content
|
59
|
+
response, error = fetch_response(uri_str, :body)
|
60
|
+
return [nil, error] unless response
|
61
|
+
|
62
|
+
tmpf = Tempfile.new('fetch_uri')
|
63
|
+
File.open(tmpf.path, 'wb') do |file|
|
64
|
+
file.write(response.body)
|
65
|
+
end
|
66
|
+
if content_disposition = response['Content-Disposition']
|
67
|
+
original_filename = content_disposition[/filename\s*=\s*('|")(.+)\1/,2]
|
68
|
+
else
|
69
|
+
original_filename = uri_str.split('/').last
|
70
|
+
end
|
71
|
+
|
72
|
+
[uploaded_file(tmpf, original_filename, response['Content-Type'])]
|
73
|
+
end
|
74
|
+
|
75
|
+
def fetch_response(uri_str, type = :body, limit = 10)
|
76
|
+
return [nil, 'too many redirects'] if limit == 0
|
77
|
+
response = nil
|
78
|
+
uri = URI.parse(URI.escape(uri_str))
|
79
|
+
return [nil, 'invalid url'] unless uri.kind_of?(URI::HTTP)
|
80
|
+
Net::HTTP.new(uri.host, uri.port).start do |http|
|
81
|
+
if type == :body
|
82
|
+
response = http.request_get(uri.request_uri)
|
83
|
+
else
|
84
|
+
response = http.head(uri.request_uri)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
case response
|
89
|
+
when Net::HTTPSuccess
|
90
|
+
response
|
91
|
+
when Net::HTTPRedirection
|
92
|
+
redirect = response['location']
|
93
|
+
port = (uri.scheme == 'http' && uri.port == 80) ? '' : ":#{uri.port}"
|
94
|
+
redirect = "#{uri.scheme}://#{uri.host}#{port}/#{redirect}" unless redirect =~ /\A\w+:\/\//
|
95
|
+
fetch_response(redirect, type, limit - 1)
|
96
|
+
else
|
97
|
+
[nil, 'not found']
|
98
|
+
end
|
99
|
+
rescue URI::InvalidURIError
|
100
|
+
[nil, 'invalid url']
|
101
|
+
end
|
102
|
+
|
103
|
+
def render_get_uf
|
104
|
+
@uuid = params[:uuid]
|
105
|
+
render :inline => "<%= link_to_function(_('cancel'), \"['file', 'upload_field'].each(Element.toggle);$('upload_field').innerHTML = '';\")%><%= upload_field %>"
|
106
|
+
end
|
107
|
+
|
108
|
+
def render_upload_progress
|
109
|
+
# When using the mod_upload_progress module, this is never hit:
|
110
|
+
# <Location /upload_progress>
|
111
|
+
# ReportUploads On
|
112
|
+
# </Location>
|
113
|
+
#
|
114
|
+
# When using Mongrel: mimic apache2 mod_upload_progress
|
115
|
+
#
|
116
|
+
# if (!found) {
|
117
|
+
# response = apr_psprintf(r->pool, "new Object({ 'state' : 'starting' })");
|
118
|
+
# } else if (err_status >= HTTP_BAD_REQUEST ) {
|
119
|
+
# response = apr_psprintf(r->pool, "new Object({ 'state' : 'error', 'status' : %d })", err_status);
|
120
|
+
# } else if (done) {
|
121
|
+
# response = apr_psprintf(r->pool, "new Object({ 'state' : 'done' })");
|
122
|
+
# } else if ( length == 0 && received == 0 ) {
|
123
|
+
# response = apr_psprintf(r->pool, "new Object({ 'state' : 'starting' })");
|
124
|
+
# } else {
|
125
|
+
# response = apr_psprintf(r->pool, "new Object({ 'state' : 'uploading', 'received' : %d, 'size' : %d, 'speed' : %d })", received, length, speed);
|
126
|
+
# }
|
127
|
+
render :update do |page|
|
128
|
+
begin
|
129
|
+
@status = Mongrel::Uploads.check(params[:"X-Progress-ID"])
|
130
|
+
if @status
|
131
|
+
if @status[:received] != @status[:size]
|
132
|
+
page << "new Object({ 'state' : 'uploading', 'received' : #{@status[:received]}, 'size' : #{@status[:size]} })"
|
133
|
+
else
|
134
|
+
page << "new Object({ 'state' : 'done' })"
|
135
|
+
end
|
136
|
+
else
|
137
|
+
#page << "new Object({ 'state' : 'done' })"
|
138
|
+
end
|
139
|
+
rescue NameError
|
140
|
+
page << "new Object({ 'state' : 'upload in progress..' })"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end # ControllerMethods
|
145
|
+
|
146
|
+
module ViewMethods
|
147
|
+
UPLOAD_KEY = defined?(Mongrel) ? 'upload_id' : "X-Progress-ID"
|
148
|
+
def upload_form_tag(url_opts, html_opts = {})
|
149
|
+
@uuid = UUIDTools::UUID.random_create.to_s.gsub('-','')
|
150
|
+
html_opts.reverse_merge!(:multipart => true, :id => "UploadForm#{@uuid}")
|
151
|
+
if html_opts[:multipart]
|
152
|
+
html_opts[:onsubmit] = "submitUploadForm('#{html_opts[:id]}', '#{@uuid}');"
|
153
|
+
url_opts[UPLOAD_KEY] = @uuid
|
154
|
+
end
|
155
|
+
if block_given?
|
156
|
+
form_tag( url_opts, html_opts ) do |f|
|
157
|
+
yield(f)
|
158
|
+
end
|
159
|
+
else
|
160
|
+
form_tag( url_opts, html_opts )
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def upload_field(opts = {})
|
165
|
+
case opts[:type]
|
166
|
+
when :onclick
|
167
|
+
link = link_to_remote(_("change"), :update=>'upload_field', :url => get_uf_documents_path(:uuid => @uuid), :method => :get, :complete=>"['file', 'upload_field'].each(Element.toggle);")
|
168
|
+
<<-TXT
|
169
|
+
<label for='attachment'>#{_('file')}</label>
|
170
|
+
<div id="file" class='toggle_div'>#{link}</div>
|
171
|
+
<div id="upload_field" class='toggle_div' style='display:none;'></div>
|
172
|
+
TXT
|
173
|
+
else
|
174
|
+
attach_file_id, attach_url_id = "af#{@uuid}", "au#{@uuid}"
|
175
|
+
onchange = %Q{onchange="Zena.get_filename(this,'node_v_title'); $('node_v_title').focus(); $('node_v_title').select();"}
|
176
|
+
<<-TXT
|
177
|
+
<div id='#{attach_file_id}' class='attach'><label for='attachment' onclick=\"['#{attach_file_id}', '#{attach_url_id}'].each(Element.toggle);\">#{_('file')} / <span class='off'>#{_('url')}</span></label>
|
178
|
+
<input style='line-height:1.5em;' id="attachment#{@uuid}" name="attachment" #{onchange} class='file' type="file" /></div>
|
179
|
+
|
180
|
+
<div id='#{attach_url_id}' class='attach' style='display:none;'><label for='url' onclick=\"['#{attach_file_id}', '#{attach_url_id}'].each(Element.toggle);\"><span class='off'>#{_('file')}</span> / #{_('url')}</label>
|
181
|
+
<input style='line-height:1.5em;' size='30' id='attachment_url' type='text' #{onchange} name='attachment_url'/><br/></div>
|
182
|
+
TXT
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end # ViewMethods
|
186
|
+
end # Upload
|
187
|
+
end # Use
|
188
|
+
end # Zena
|