zena 0.16.4 → 0.16.5

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.
data/History.txt CHANGED
@@ -1,11 +1,22 @@
1
+ == 0.16.5 2010-04-15
2
+
3
+ * 2 major enhancements
4
+ * added a way to easily check duplicate names when adding documents
5
+ * ruby 1.9 compatibility fixes
6
+
7
+ * 3 minor enhancements
8
+ * better default +login mode
9
+ * fixed image cache stamp not always used
10
+ * some minor bug fixes
11
+
1
12
  == 0.16.4 2010-02-22
2
13
 
3
- * 3 major enhancement
14
+ * 3 major enhancements
4
15
  * fixed installation and runtime bugs on Windows
5
16
  * moved ruby files in 'lib' into their Zena namespace
6
17
  * german translations [Lars Kanis]
7
18
 
8
- * 2 minor enhancments
19
+ * 2 minor enhancements
9
20
  * fixed edgy bug with name duplicates
10
21
  * fixed bug that would show a 'site not found' error instead of a 404
11
22
 
@@ -28,13 +39,13 @@
28
39
 
29
40
  == 0.16.0 2010-01-15
30
41
 
31
- * 3 major enhancements:
42
+ * 3 major enhancements
32
43
  * Sphinx search support
33
44
  * Authlogic authentification
34
45
  * attachments can now be provided with an url
35
46
  * added [node:attribute_name] to use in querybuilder
36
47
 
37
- * 5 minor enhancement
48
+ * 5 minor enhancements
38
49
  * logrotate setup support with capistrano
39
50
  * fixed contact content zip bug
40
51
  * fixed fullpath set to NULL instead of kept in sync
@@ -48,11 +59,11 @@
48
59
 
49
60
  == 0.15.1 2009-10-27
50
61
 
51
- * 2 major enhancements:
62
+ * 2 major enhancements
52
63
  * Passenger support (deploy, upload progress)
53
64
  * JS popup & gallery support (setting in image formats)
54
65
 
55
- * 6 minor enhancements:
66
+ * 6 minor enhancements
56
67
  * fixed some deployment tasks (capistrano)
57
68
  * fixed zena:setup task to copy files instead of symlink
58
69
  * better versions list and diff select
@@ -62,19 +73,19 @@
62
73
 
63
74
  == 0.15.0 2009-10-16
64
75
 
65
- * 5 major enhancements:
76
+ * 5 major enhancements
66
77
  * running rails 2.3.4
67
78
  * installable as gem without RMagick
68
79
  * usable as gem with config.gem
69
80
  * supports sqlite3
70
81
  * 'zena' command to create app
71
82
 
72
- * 3 minor enhancemnts:
83
+ * 3 minor enhancemnts
73
84
  * huge speed improvement in version loading
74
85
  * massive code cleanup
75
86
  * better team workflow (reworked access rights)
76
87
 
77
88
  == 0.11.1 2009-04-03
78
89
 
79
- * minor enhancements:
90
+ * minor enhancements
80
91
  * Better testing of custom queries using latest querybuilder (0.5.2)
data/README.rdoc CHANGED
@@ -1,63 +1,61 @@
1
- == DESCRIPTION:
1
+ = DESCRIPTION:
2
2
 
3
3
  CMS with super natural powers, based on Ruby on Rails
4
4
 
5
5
  website: http://zenadmin.org
6
6
  licence: MIT
7
7
 
8
- == Getting started
8
+ = Getting started
9
9
 
10
- # sudo gem sources -a http://gems.github.com
11
10
  # sudo gem install zena
12
11
  # zena myapp
12
+ # cd myapp
13
+ # rake zena:init RAILS_ENV=production
13
14
 
14
- == Details
15
+ You can now visit http://localhost:3000 (user = admin, password = admin)
15
16
 
16
- Have a look at the generator used by 'zena' command:
17
+ These commands do the following:
17
18
 
18
- http://github.com/zena/zena/blob/master/config/zena.rb
19
+ 1. Install the zena gem and dependencies
20
+ 2. Create an empty application
21
+ 3. ...
22
+ 4. Create the database, migrate, create the 'localhost' website in 'production' environment and start server.
19
23
 
20
- == Production
24
+ The 'zena:init' rake task does the following:
21
25
 
22
- THE INSTRUCTIONS BELOW NO LONGER APPLY (they need an update since the way to go is
23
- to use zena as a gem).
24
-
25
- You should use capistrano to ease deployment. See 'config/delploy.rb'.
26
+ # rake db:create RAILS_ENV=production
27
+ # rake zena:migrate
28
+ # rake zena:mksite LANG=en RAILS_ENV=production PASSWORD=admin HOST=localhost
29
+ # script/server -e production
26
30
 
27
- Manual deployment is done with the following commands:
28
- 1. Create the database with (using a mysql client)
29
- create database zena DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
31
+ Read more: http://zenadmin.org/documentation
30
32
 
31
- 2. Create log directory
32
- mkdir log
33
+ == Details
33
34
 
34
- 3. Rename 'config/database_example.yml' to 'config/database.yml' and update it's content
35
- (change user, password if needed)
35
+ Have a look at the generator used by 'zena' command:
36
36
 
37
- 4. Migrate the database
38
- rake zena:migrate RAILS_ENV=production
37
+ http://github.com/zena/zena/blob/master/config/zena.rb
39
38
 
40
- 4. Create a site
41
- rake zena:mksite HOST=example.com PASSWORD=secret LANG=en RAILS_ENV=production
39
+ === Production
42
40
 
43
- 5. Login user is 'admin', password is the one set on the line above.
41
+ You should use capistrano to ease deployment. See 'config/delploy.rb'.
44
42
 
45
- == Create a new site
43
+ === Create a new site
46
44
  # rake zena:mksite HOST=example.com PASSWORD=secret RAILS_ENV=production
47
45
 
48
- == Start
46
+ === Start
49
47
  # ruby lib/upload_progress_server.rb start
50
48
  # script/server -S config/mongrel_upload_progress.conf
51
49
 
52
- == Stop
50
+ === Stop
53
51
  # ^C (interrupt)
54
52
  # ruby lib/upload_progress_server.rb stop
55
53
 
56
54
 
57
- == Login
55
+ === Login
58
56
  You can now login with 'admin' and the password you used to make the site.
59
57
 
60
- == Dependencies
58
+ === Dependencies
61
59
 
62
60
  === 1. Original in debian etch (might need to replace jpeg by libjpeg62)
63
61
  # aptitude install build-essential apache2 mysql-server libmagick9-dev gs-gpl libssl-dev gettext libgettext-ruby libreadline5 libreadline5-dev zlib1g-dev libncurses5 libncurses5-dev unzip liburi-perl libjpeg-dev subversion ssh sudo awstats
@@ -110,7 +108,7 @@ Versions:
110
108
  monit (debian package to monitor your mongrel processes)
111
109
 
112
110
 
113
- == Very experimental webDAV
111
+ === Very experimental webDAV
114
112
  Should not be used for production.
115
113
 
116
114
  add this to nodes_controller macros:
data/Rakefile CHANGED
@@ -29,6 +29,7 @@ begin
29
29
  # Gem dependecies
30
30
  Zena.gem_configuration.each do |gem_name, gem_config|
31
31
  if gem_config
32
+ next if gem_config['optional']
32
33
  if gem_config['development_only']
33
34
  gemspec.add_development_dependency(gem_name, gem_config['version'])
34
35
  else
@@ -291,29 +291,50 @@ class NodesController < ApplicationController
291
291
  # AJAX HELPER
292
292
  # TODO: test
293
293
  def attribute
294
- method = params[:attr].to_sym
295
- if [:v_text, :v_summary, :name, :path, :short_path].include?(method)
294
+ method = params[:attr]
295
+ if (params[:pseudo_id] || params[:name]).blank? || !%w{v_title v_text v_summary name path short_path}.include?(method)
296
+ # Error
297
+ render :text => ''
298
+ return
299
+ end
300
+
301
+ if id_query = params[:pseudo_id]
296
302
  # '+' are not escaped as they should in ajax query
297
- params[:node].sub!(/ +$/) {|spaces| '+' * spaces.length} if params[:node]
298
- node_id = secure!(Node) { Node.translate_pseudo_id(params[:node], :id, @node)}
303
+ id_query.sub!(/ +$/) {|spaces| '+' * spaces.length }
304
+ node_id = secure!(Node) { Node.translate_pseudo_id(id_query, :id, @node)}
299
305
  @node = secure!(Node) { Node.find(node_id) }
306
+ elsif name_query = params[:name]
307
+ if name_query =~ /^(.*)\.[a-z]{2,3}$/
308
+ name_query = $1
309
+ end
300
310
 
301
- if method == :path || method == :short_path
302
- path = @node.send(method)
303
- render :inline=> path.join('/ ')
304
- else
305
- @text = @node.send(method)
306
- if [:v_text, :v_summary].include?(method)
307
- render :inline=>"<%= zazen(@text) %>"
308
- else
309
- render :inline=>@text
310
- end
311
+ conditions = [[]]
312
+
313
+ if kpath = params[:kpath]
314
+ conditions[0] << "kpath LIKE ?"
315
+ conditions << "#{kpath}%"
311
316
  end
317
+
318
+ conditions[0] << "name LIKE ?"
319
+ conditions << "#{name_query}%"
320
+
321
+ conditions[0] = conditions[0].join(' AND ')
322
+ @node = secure!(Node) { Node.find(:first, :conditions => conditions, :order => "zip DESC")}
323
+ end
324
+
325
+ if %w{path short_path}.include?(method)
326
+ path = @node.send(method)
327
+ render :text => path.join('/ ')
312
328
  else
313
- render :inline=>method
329
+ @text = @node.send(method)
330
+ if %w{v_text v_summary}.include?(method)
331
+ render :text => "<%= zazen(@text) %>"
332
+ else
333
+ render :text => @text
334
+ end
314
335
  end
315
336
  rescue ActiveRecord::RecordNotFound
316
- render :inline=>_('node not found')
337
+ render :text => (params[:pseudo_id] ? _('node not found') : _('new'))
317
338
  end
318
339
 
319
340
  # TODO: test
data/app/models/node.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  =begin rdoc
2
3
  A Node is the root class of all elements in the zena application. Class inheritance diagram:
3
4
 
@@ -250,7 +251,8 @@ class Node < ActiveRecord::Base
250
251
 
251
252
  # Return class or virtual class from name.
252
253
  def get_class(rel, opts={})
253
- class_name = rel.singularize.camelize # mushroom_types ==> MushroomType
254
+ # mushroom_types ==> MushroomType
255
+ class_name = rel =~ /\A[a-z]/ ? rel.singularize.camelize : rel
254
256
  begin
255
257
  klass = Module.const_get(class_name)
256
258
  raise NameError unless klass.ancestors.include?(Node)
@@ -1716,4 +1718,4 @@ class Node < ActiveRecord::Base
1716
1718
 
1717
1719
  end
1718
1720
 
1719
- Bricks.apply_patches
1721
+ Bricks.apply_patches
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  class VirtualClass < ActiveRecord::Base
2
3
  attr_accessor :import_result
3
4
  belongs_to :create_group, :class_name => 'Group', :foreign_key => 'create_group_id'
@@ -1,32 +1,39 @@
1
1
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
2
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" do='void' lang="en" set_lang='[v_lang]' xml:lang='en'>
4
- <head>
5
- <title do='title_for_layout' do='trans'>login</title>
6
- <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
7
- <meta http-equiv="Content-Language" do='void' content='fr-fr' tset_content='[v_lang]_content'/>
8
3
 
9
- <r:stylesheets name='stylesheets' list='reset,zena,default'/>
4
+ <html xmlns="http://www.w3.org/1999/xhtml" do='void' lang="en" set_lang='[v_lang]' xml:lang='en'>
5
+ <head>
6
+ <title do='[v_title]' name='title'>Zena site</title>
7
+ <r:stylesheets list='reset'/>
8
+ <style>
9
+ body { color:#666; background: #ddd url('') no-repeat; font:13px Verdana, Helvetica, sans-serif; }
10
+ a { color:#922; text-decoration:none;}
11
+ .welcome { text-align:center; border-bottom:1px solid grey; padding:10px; background:#aaa; color:#333;}
12
+ table { margin:20px;}
13
+ td { padding:5px; }
14
+ #login_form { border:1px solid grey; background:#eee; width:400px; margin:200px auto; padding:0;}
15
+ </style>
10
16
  </head>
11
- <body>
12
- <!-- There was a problem with the rendering of the original zafu code. Using default '+login' template. -->
13
- <div id='login_form'><div>
14
- <form action="/session" method="post"> <table>
15
- <tr>
16
- <td><label for='user_login' do='trans'>User name:</label></td>
17
- <td><input name="login" size="20" type="text" /></td>
18
- </tr>
19
- <tr>
20
- <td><label for='user_password' do='trans'>Password:</label></td>
21
17
 
22
- <td><input name="password" size="20" type="password" /></td>
23
- </tr>
24
- <tr><td></td><td><input name="commit" type="submit" value=" login " /></td></tr>
25
- </table>
26
- </form></div>
27
- </div>
18
+ <body do='void' name='body'>
19
+ <div id='login_form'>
20
+ <p class='welcome'><r:t>Login for</r:t> <b do='[v_title]'/></p>
21
+ <form action="/session" method="post"> <table>
22
+ <tr>
23
+ <td><label for='user_login' do='trans'>User name:</label></td>
24
+ <td><input id='user_login' name="login" size="20" type="text" /></td>
25
+ </tr>
26
+ <tr>
27
+ <td><label for='user_password' do='trans'>Password:</label></td>
28
+
29
+ <td><input name="password" size="20" type="password" /></td>
30
+ </tr>
31
+ <tr><td></td><td><input name="commit" type="submit" value=" login " /></td></tr>
32
+ </table>
33
+ </form>
34
+ </div>
28
35
  <script type="text/javascript">
29
36
  window.onload = document.getElementById('user_login').focus();
30
37
  </script>
31
38
  </body>
32
- </html>
39
+ </html>
@@ -5,7 +5,7 @@
5
5
  <%= upload_field %>
6
6
 
7
7
  <label for='node_name'><%= _('title') %></label>
8
- <input id='node_v_title' type='text' name='node[v_title]'/><br/>
8
+ <input id='node_v_title' type='text' name='node[v_title]' onchange="Zena.get_filename(this,'existing_doc');"/> <%= check_exists(:node => @parent, :watch => 'node_v_title', :kpath => 'ND', :show => 'short_path') %><br/>
9
9
 
10
10
  <label for='node_v_summary'><%= _('summary') %></label>
11
11
  <textarea id='node_v_summary' rows='3' name='node[v_summary]'></textarea><br/>
@@ -97,6 +97,8 @@ namespace :sphinx do
97
97
  sphinx_conf.controller.start
98
98
 
99
99
  if ThinkingSphinx.sphinx_running?
100
+ # We need to read the pid file from within Zena application (run under www-data user).
101
+ `chown www-data:www-data #{sphinx_conf.pid_file}`
100
102
  puts "Sphinx searchd: started successfully (pid #{ThinkingSphinx.sphinx_pid})."
101
103
  else
102
104
  tail = `tail -n 10 #{sphinx_conf.searchd_log_file.inspect}`
@@ -134,5 +136,4 @@ namespace :sphinx do
134
136
  puts "Sphinx searchd: indexing failed\n#{res}"
135
137
  end
136
138
  end
137
-
138
139
  end
@@ -65,4 +65,20 @@ namespace :worker do
65
65
  sleep(1)
66
66
  worker.start
67
67
  end
68
+
69
+ desc "Run worker jobs index requests (never returns)"
70
+ task :run => :environment do
71
+ require 'delayed/worker'
72
+ begin
73
+ require 'thinking_sphinx/deltas/delayed_delta'
74
+ rescue LoadError
75
+ # Ignore
76
+ end
77
+
78
+ Delayed::Worker.new(
79
+ :min_priority => ENV['MIN_PRIORITY'],
80
+ :max_priority => ENV['MAX_PRIORITY']
81
+ ).start
82
+ end
83
+
68
84
  end
@@ -12,7 +12,7 @@ ARGV.each do |arg|
12
12
  end
13
13
 
14
14
  unless %w{index start stop restart}.include?(cmd)
15
- puts "Usage: script/sphinx RAILS_ENV=production [index|start|stop|restart]"
15
+ puts "Usage: script/worker RAILS_ENV=production [start|stop|restart]"
16
16
  exit -1
17
17
  end
18
18
 
@@ -22,7 +22,9 @@ daemon_options = {
22
22
  :multiple => false,
23
23
  :dir_mode => :normal,
24
24
  :dir => File.join(dir, 'log'),
25
- :backtrace => true
25
+ :backtrace => true,
26
+ # Create a worker.output to redirect STDOUT and STDERR
27
+ :log_output => true,
26
28
  }
27
29
 
28
30
  ARGV.clear
@@ -34,7 +36,15 @@ Daemons.run_proc('worker', daemon_options) do
34
36
  Dir.chdir dir
35
37
  ENV['RAILS_ENV'] = RAILS_ENV = env
36
38
  require File.join('config', 'environment')
37
- require 'delayed_job'
39
+
40
+ require 'delayed/worker'
41
+ begin
42
+ require 'thinking_sphinx/deltas/delayed_delta'
43
+ rescue LoadError
44
+ # Ignore
45
+ end
46
+
47
+ puts "Starting worker..."
38
48
 
39
49
  Delayed::Worker.new.start
40
50
  end
data/config/bricks.yml CHANGED
@@ -8,14 +8,14 @@ development:
8
8
  tags: ON
9
9
  captcha: ON
10
10
  sphinx:
11
- switch: OFF
11
+ switch: ON
12
12
  activate_if:
13
13
  gem: 'thinking_sphinx'
14
14
  adapter: 'mysql,postgresql'
15
15
  run_if:
16
16
  file: 'log/searchd.development.pid'
17
17
  worker:
18
- switch: OFF
18
+ switch: ON
19
19
  activate_if:
20
20
  gem: 'delayed_job'
21
21
 
@@ -23,7 +23,7 @@ production:
23
23
  tags: ON
24
24
  captcha: ON
25
25
  sphinx:
26
- switch: OFF
26
+ switch: ON
27
27
  activate_if:
28
28
  gem: 'thinking_sphinx'
29
29
  adapter: 'mysql,postgresql'
data/config/gems.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  hpricot:
2
- gettext: '= 1.93.0'
2
+ gettext: '>= 1.93.0'
3
3
  querybuilder: '= 0.5.8'
4
4
  rubyless: '>= 0.3.5'
5
5
  ruby-recaptcha: '= 1.0.0'
@@ -1,9 +1,23 @@
1
- <r:include template='Node'>
2
- <r:with part='menu'/>
3
- <r:with part='visitor'/>
4
- <r:with part='search'/>
5
- <r:with part='container'>
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" do='void' lang="en" set_lang='[v_lang]' xml:lang='en'>
5
+ <head>
6
+ <title do='[v_title]' name='title'>Zena site</title>
7
+ <r:stylesheets list='reset'/>
8
+ <style>
9
+ body { color:#666; background: #ddd url('') no-repeat; font:13px Verdana, Helvetica, sans-serif; }
10
+ a { color:#922; text-decoration:none;}
11
+ .welcome { text-align:center; border-bottom:1px solid grey; padding:10px; background:#aaa; color:#333;}
12
+ table { margin:20px;}
13
+ td { padding:5px; }
14
+ #login_form { border:1px solid grey; background:#eee; width:400px; margin:200px auto; padding:0;}
15
+ </style>
16
+ </head>
17
+
18
+ <body do='void' name='body'>
6
19
  <div id='login_form'>
20
+ <p class='welcome'><r:t>Login for</r:t> <b do='[v_title]'/></p>
7
21
  <form action="/session" method="post"> <table>
8
22
  <tr>
9
23
  <td><label for='user_login' do='trans'>User name:</label></td>
@@ -21,5 +35,5 @@
21
35
  <script type="text/javascript">
22
36
  window.onload = document.getElementById('user_login').focus();
23
37
  </script>
24
- </r:with>
25
- </r:include>
38
+ </body>
39
+ </html>
data/db/schema.rb CHANGED
@@ -80,6 +80,19 @@ ActiveRecord::Schema.define(:version => 20100115134729) do
80
80
  t.decimal "value_b", :precision => 24, :scale => 8
81
81
  end
82
82
 
83
+ create_table "delayed_jobs", :force => true do |t|
84
+ t.integer "priority", :default => 0
85
+ t.integer "attempts", :default => 0
86
+ t.text "handler"
87
+ t.text "last_error"
88
+ t.datetime "run_at"
89
+ t.datetime "locked_at"
90
+ t.datetime "failed_at"
91
+ t.string "locked_by"
92
+ t.datetime "created_at"
93
+ t.datetime "updated_at"
94
+ end
95
+
83
96
  create_table "discussions", :force => true do |t|
84
97
  t.datetime "created_at"
85
98
  t.datetime "updated_at"
@@ -176,6 +189,7 @@ ActiveRecord::Schema.define(:version => 20100115134729) do
176
189
  t.integer "custom_a"
177
190
  t.integer "custom_b"
178
191
  t.text "vhash"
192
+ t.boolean "delta", :default => true, :null => false
179
193
  end
180
194
 
181
195
  create_table "relations", :force => true do |t|
@@ -8,15 +8,14 @@ module Bricks
8
8
  errors = []
9
9
  requirements.each do |k,v|
10
10
  case k
11
- # bad idea, this is run before gem version configuration
12
- # when 'gem'
13
- # v.split(',').each do |name|
14
- # begin
15
- # require name.strip
16
- # rescue LoadError => err
17
- # errors << "'#{name}' missing"
18
- # end
19
- # end
11
+ when 'gem'
12
+ v.split(',').each do |name|
13
+ begin
14
+ require name.strip
15
+ rescue LoadError => err
16
+ errors << "'#{name}' missing"
17
+ end
18
+ end
20
19
  when 'file'
21
20
  v.split(',').each do |name|
22
21
  unless File.exist?("#{RAILS_ROOT}/#{name}")
@@ -52,7 +51,7 @@ module Bricks
52
51
  if defined?(ActiveRecord::Base) && logger = ActiveRecord::Base.logger
53
52
  ActiveRecord::Base.logger.warn "'#{brick}' not activated: #{errors.join(', ')}"
54
53
  end
55
- puts "'#{brick}' not activated: #{errors.join(', ')}" if RAILS_ENV == 'development'
54
+ # puts "'#{brick}' not activated: #{errors.join(', ')}" if RAILS_ENV == 'development'
56
55
  end
57
56
  end
58
57
  config[brick] = opts unless errors
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  # FIXME: do we really need to monkey patch String ?
2
3
 
3
4
  # Avoid incompatibility with rails 'chars' version in Ruby 1.8.7
@@ -71,4 +72,4 @@ class String
71
72
  (root + path).join('/')
72
73
  end
73
74
 
74
- end
75
+ end
data/lib/zena/info.rb CHANGED
@@ -9,7 +9,7 @@ ZENA_CALENDAR_LANGS = ["en", "fr", "de"] # FIXME: build this dynamically from ex
9
9
  ENABLE_XSENDFILE = false
10
10
 
11
11
  module Zena
12
- VERSION = '0.16.4'
12
+ VERSION = '0.16.5'
13
13
  REVISION = 1336
14
14
  ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
15
15
  end
data/lib/zena/use/grid.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'json'
2
3
 
3
4
  module Zena
@@ -145,4 +146,4 @@ module Zena
145
146
  end
146
147
  end # Grid
147
148
  end # Use
148
- end # Zena
149
+ end # Zena
@@ -307,11 +307,42 @@ module Zena
307
307
  end
308
308
  input_id = opt[:input_id] ? " id='#{params[:input_id]}'" : ''
309
309
  # we use both 'onChange' and 'onKeyup' for old javascript compatibility
310
- update = "new Ajax.Updater('#{name_ref}', '/nodes/#{(node || @node).zip}/attribute?node=' + this.value + '&attr=#{attribute}', {method:'get', asynchronous:true, evalScripts:true});"
310
+ update = "new Ajax.Updater('#{name_ref}', '/nodes/#{(node || @node).zip}/attribute?pseudo_id=' + this.value + '&attr=#{attribute}', {method:'get', asynchronous:true, evalScripts:true});"
311
311
  "<div class='select_id'><input type='text' size='8'#{input_id} name='#{obj}[#{sym}]' value='#{zip}' onChange=\"#{update}\" onKeyup=\"#{update}\"/>"+
312
312
  "<span class='select_id_name' id='#{name_ref}'>#{current}</span></div>"
313
313
  end
314
314
 
315
+ # TODO: select_id should use 'check_exists'
316
+ def check_exists(opts)
317
+ watch = opts[:watch] || 'node_v_title'
318
+ name_ref = unique_id
319
+ params = []
320
+
321
+ # Filtering key
322
+ key = 'name'
323
+ params << "#{key}=' + this.value + '"
324
+
325
+ # Attribute to display
326
+ attribute = opts[:show] || 'short_path'
327
+ params << "attr=#{attribute}"
328
+
329
+ # Scoping
330
+ if kpath = opts[:kpath]
331
+ params << "kpath=#{kpath}"
332
+ end
333
+
334
+ function_name = "check#{unique_id}"
335
+ js_data << "#{function_name} = function(event) {
336
+ new Ajax.Updater('#{name_ref}', '/nodes/#{(opts[:node] || @node).zip}/attribute?#{params.join('&')}', {method:'get', asynchronous:true, evalScripts:true});
337
+ };"
338
+
339
+ js_data << "$('#{watch}').check_exists = #{function_name};"
340
+ js_data << "Event.observe('#{watch}', 'change', #{function_name});"
341
+ js_data << "Event.observe('#{watch}', 'keyup', #{function_name});"
342
+
343
+ "<span class='select_id_name' id='#{name_ref}'>#{opts[:current]}</span>"
344
+ end
345
+
315
346
  def unique_id
316
347
  @counter ||= 0
317
348
  "#{Time.now.to_i}_#{@counter += 1}"
@@ -241,6 +241,9 @@ module Zena
241
241
  path = ((path.empty? || path == "/") ? "/index" : URI.unescape(path))
242
242
  ext = params[:format].blank? ? 'html' : params[:format]
243
243
  path << ".#{ext}" unless path =~ /\.#{ext}(\?\d+|)$/
244
+ if cachestamp_format?(params['format'])
245
+ path << "?" << make_cachestamp(@node, params['mode'])
246
+ end
244
247
  path
245
248
  end
246
249
 
@@ -132,6 +132,9 @@ Zena.get_filename = function(source, target) {
132
132
  var path = $(source).value;
133
133
  var elements = path.split(/[\\\/]+/g);
134
134
  $(target).value = elements[elements.length - 1];
135
+ if ($(target).check_exists) {
136
+ $(target).check_exists();
137
+ }
135
138
  }
136
139
  }
137
140
 
@@ -68,7 +68,7 @@ class NodesControllerTest < Zena::Controller::TestCase
68
68
  # cache info ok
69
69
  get 'show', :prefix => 'en', :path => ["image#{node.zip}.jpg"], :cachestamp => node.updated_at.to_i
70
70
  assert_response :success
71
- assert File.exist?("#{SITES_ROOT}/test.host/public/en/image#{node.zip}.jpg")
71
+ assert File.exist?("#{SITES_ROOT}/test.host/public/en/image#{node.zip}.jpg?#{node.updated_at.to_i}")
72
72
  end
73
73
  end
74
74
  end
@@ -136,7 +136,8 @@ END:VCALENDAR
136
136
  node = secure!(Node) { nodes(:style_css) }
137
137
  without_files('/test.host/public') do
138
138
  name = "textdocument#{node.zip}.css"
139
- filename = "#{SITES_ROOT}/test.host/public/en/#{name}"
139
+ base_filename = "#{SITES_ROOT}/test.host/public/en/#{name}"
140
+ filename = "#{base_filename}?#{node.updated_at.to_i}"
140
141
  with_caching do
141
142
  assert !File.exist?(filename)
142
143
  get 'show', :prefix => 'en', :path => [name], :cachestamp => node.updated_at.to_i
@@ -148,11 +149,13 @@ END:VCALENDAR
148
149
  assert node.errors.empty?
149
150
  assert_equal Zena::Status[:pub], node.version.status
150
151
  assert_equal versions_id(:style_css_en), node.version.id # auto publish
151
- assert !File.exist?(filename) # cached page removed
152
+ assert !File.exist?(filename) # old cached page removed
153
+ filename = "#{base_filename}?#{node.updated_at.to_i}"
154
+ assert !File.exist?(filename) # not yet created
152
155
  get 'show', :prefix => 'en', :path => [name], :cachestamp => node.updated_at.to_i
153
156
  assert_response :success
154
- assert_match %r[/\* empty \*/], File.read(filename)
155
157
  assert File.exist?(filename) # cached page created again
158
+ assert_match %r[/\* empty \*/], File.read(filename)
156
159
  end
157
160
  end
158
161
  end
@@ -869,6 +869,12 @@ class NodeTest < Zena::Unit::TestCase
869
869
  assert_equal TextDocument, Node.get_class('TextDocument')
870
870
  end
871
871
 
872
+ def test_get_class_without_plural
873
+ login(:lion)
874
+ vclass = VirtualClass.create(:superclass => 'Project', :name => 'Process', :create_group_id => groups_id(:public))
875
+ assert_equal vclass, Node.get_class('Process')
876
+ end
877
+
872
878
  def test_get_attributes_from_yaml
873
879
  f = Tempfile.new('any.yml')
874
880
  path = f.path
data/zena.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{zena}
8
- s.version = "0.16.4"
8
+ s.version = "0.16.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gaspard Bucher"]
12
- s.date = %q{2010-02-22}
12
+ s.date = %q{2010-04-15}
13
13
  s.default_executable = %q{zena}
14
14
  s.description = %q{zena is a Ruby on Rails CMS (content managment system) with a focus on usability, ease of customization and web 2.0 goodness (application like behaviour).}
15
15
  s.email = %q{gaspard@teti.ch}
@@ -1918,7 +1918,7 @@ Gem::Specification.new do |s|
1918
1918
  s.rdoc_options = ["--charset=UTF-8"]
1919
1919
  s.require_paths = ["lib"]
1920
1920
  s.rubyforge_project = %q{zena}
1921
- s.rubygems_version = %q{1.3.5}
1921
+ s.rubygems_version = %q{1.3.6}
1922
1922
  s.summary = %q{CMS with super natural powers, based on Ruby on Rails}
1923
1923
  s.test_files = [
1924
1924
  "spec/controllers/versions_controller_spec.rb",
@@ -2024,18 +2024,14 @@ Gem::Specification.new do |s|
2024
2024
  s.add_runtime_dependency(%q<rails>, ["= 2.3.4"])
2025
2025
  s.add_runtime_dependency(%q<uuidtools>, ["= 2.0.0"])
2026
2026
  s.add_runtime_dependency(%q<authlogic>, ["= 2.1.3"])
2027
- s.add_runtime_dependency(%q<ts-delayed-delta>, [">= 1.0.2"])
2028
2027
  s.add_runtime_dependency(%q<shoulda>, [">= 2.10.2"])
2029
2028
  s.add_runtime_dependency(%q<fast_gettext>, ["~> 0.4.16"])
2030
- s.add_runtime_dependency(%q<delayed_job>, [">= 1.8.4"])
2031
2029
  s.add_runtime_dependency(%q<syntax>, ["= 1.0.0"])
2032
2030
  s.add_runtime_dependency(%q<yamltest>, [">= 0.5.3"])
2033
- s.add_runtime_dependency(%q<thinking-sphinx>, [">= 1.3.14"])
2034
2031
  s.add_runtime_dependency(%q<json>, [">= 1.1.9"])
2035
2032
  s.add_runtime_dependency(%q<will_paginate>, ["~> 2.3.12"])
2036
- s.add_runtime_dependency(%q<gettext>, ["= 1.93.0"])
2033
+ s.add_runtime_dependency(%q<gettext>, [">= 1.93.0"])
2037
2034
  s.add_runtime_dependency(%q<jeweler>, [">= 0"])
2038
- s.add_runtime_dependency(%q<rmagick>, [">= 2.10.0"])
2039
2035
  s.add_runtime_dependency(%q<hpricot>, [">= 0"])
2040
2036
  s.add_runtime_dependency(%q<differ>, [">= 0.1.1"])
2041
2037
  s.add_runtime_dependency(%q<RedCloth>, ["= 3.0.4"])
@@ -2047,18 +2043,14 @@ Gem::Specification.new do |s|
2047
2043
  s.add_dependency(%q<rails>, ["= 2.3.4"])
2048
2044
  s.add_dependency(%q<uuidtools>, ["= 2.0.0"])
2049
2045
  s.add_dependency(%q<authlogic>, ["= 2.1.3"])
2050
- s.add_dependency(%q<ts-delayed-delta>, [">= 1.0.2"])
2051
2046
  s.add_dependency(%q<shoulda>, [">= 2.10.2"])
2052
2047
  s.add_dependency(%q<fast_gettext>, ["~> 0.4.16"])
2053
- s.add_dependency(%q<delayed_job>, [">= 1.8.4"])
2054
2048
  s.add_dependency(%q<syntax>, ["= 1.0.0"])
2055
2049
  s.add_dependency(%q<yamltest>, [">= 0.5.3"])
2056
- s.add_dependency(%q<thinking-sphinx>, [">= 1.3.14"])
2057
2050
  s.add_dependency(%q<json>, [">= 1.1.9"])
2058
2051
  s.add_dependency(%q<will_paginate>, ["~> 2.3.12"])
2059
- s.add_dependency(%q<gettext>, ["= 1.93.0"])
2052
+ s.add_dependency(%q<gettext>, [">= 1.93.0"])
2060
2053
  s.add_dependency(%q<jeweler>, [">= 0"])
2061
- s.add_dependency(%q<rmagick>, [">= 2.10.0"])
2062
2054
  s.add_dependency(%q<hpricot>, [">= 0"])
2063
2055
  s.add_dependency(%q<differ>, [">= 0.1.1"])
2064
2056
  s.add_dependency(%q<RedCloth>, ["= 3.0.4"])
@@ -2071,18 +2063,14 @@ Gem::Specification.new do |s|
2071
2063
  s.add_dependency(%q<rails>, ["= 2.3.4"])
2072
2064
  s.add_dependency(%q<uuidtools>, ["= 2.0.0"])
2073
2065
  s.add_dependency(%q<authlogic>, ["= 2.1.3"])
2074
- s.add_dependency(%q<ts-delayed-delta>, [">= 1.0.2"])
2075
2066
  s.add_dependency(%q<shoulda>, [">= 2.10.2"])
2076
2067
  s.add_dependency(%q<fast_gettext>, ["~> 0.4.16"])
2077
- s.add_dependency(%q<delayed_job>, [">= 1.8.4"])
2078
2068
  s.add_dependency(%q<syntax>, ["= 1.0.0"])
2079
2069
  s.add_dependency(%q<yamltest>, [">= 0.5.3"])
2080
- s.add_dependency(%q<thinking-sphinx>, [">= 1.3.14"])
2081
2070
  s.add_dependency(%q<json>, [">= 1.1.9"])
2082
2071
  s.add_dependency(%q<will_paginate>, ["~> 2.3.12"])
2083
- s.add_dependency(%q<gettext>, ["= 1.93.0"])
2072
+ s.add_dependency(%q<gettext>, [">= 1.93.0"])
2084
2073
  s.add_dependency(%q<jeweler>, [">= 0"])
2085
- s.add_dependency(%q<rmagick>, [">= 2.10.0"])
2086
2074
  s.add_dependency(%q<hpricot>, [">= 0"])
2087
2075
  s.add_dependency(%q<differ>, [">= 0.1.1"])
2088
2076
  s.add_dependency(%q<RedCloth>, ["= 3.0.4"])
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zena
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.4
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 16
8
+ - 5
9
+ version: 0.16.5
5
10
  platform: ruby
6
11
  authors:
7
12
  - Gaspard Bucher
@@ -9,229 +14,257 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-22 00:00:00 +01:00
17
+ date: 2010-04-15 00:00:00 +02:00
13
18
  default_executable: zena
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: ruby-recaptcha
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - "="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 0
30
+ - 0
23
31
  version: 1.0.0
24
- version:
32
+ type: :runtime
33
+ version_requirements: *id001
25
34
  - !ruby/object:Gem::Dependency
26
35
  name: tzinfo
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
30
38
  requirements:
31
39
  - - ">="
32
40
  - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 3
44
+ - 12
33
45
  version: 0.3.12
34
- version:
46
+ type: :runtime
47
+ version_requirements: *id002
35
48
  - !ruby/object:Gem::Dependency
36
49
  name: rubyless
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
40
52
  requirements:
41
53
  - - ">="
42
54
  - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ - 3
58
+ - 5
43
59
  version: 0.3.5
44
- version:
60
+ type: :runtime
61
+ version_requirements: *id003
45
62
  - !ruby/object:Gem::Dependency
46
63
  name: rails
47
- type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
50
66
  requirements:
51
67
  - - "="
52
68
  - !ruby/object:Gem::Version
69
+ segments:
70
+ - 2
71
+ - 3
72
+ - 4
53
73
  version: 2.3.4
54
- version:
74
+ type: :runtime
75
+ version_requirements: *id004
55
76
  - !ruby/object:Gem::Dependency
56
77
  name: uuidtools
57
- type: :runtime
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
60
80
  requirements:
61
81
  - - "="
62
82
  - !ruby/object:Gem::Version
83
+ segments:
84
+ - 2
85
+ - 0
86
+ - 0
63
87
  version: 2.0.0
64
- version:
88
+ type: :runtime
89
+ version_requirements: *id005
65
90
  - !ruby/object:Gem::Dependency
66
91
  name: authlogic
67
- type: :runtime
68
- version_requirement:
69
- version_requirements: !ruby/object:Gem::Requirement
92
+ prerelease: false
93
+ requirement: &id006 !ruby/object:Gem::Requirement
70
94
  requirements:
71
95
  - - "="
72
96
  - !ruby/object:Gem::Version
97
+ segments:
98
+ - 2
99
+ - 1
100
+ - 3
73
101
  version: 2.1.3
74
- version:
75
- - !ruby/object:Gem::Dependency
76
- name: ts-delayed-delta
77
102
  type: :runtime
78
- version_requirement:
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: 1.0.2
84
- version:
103
+ version_requirements: *id006
85
104
  - !ruby/object:Gem::Dependency
86
105
  name: shoulda
87
- type: :runtime
88
- version_requirement:
89
- version_requirements: !ruby/object:Gem::Requirement
106
+ prerelease: false
107
+ requirement: &id007 !ruby/object:Gem::Requirement
90
108
  requirements:
91
109
  - - ">="
92
110
  - !ruby/object:Gem::Version
111
+ segments:
112
+ - 2
113
+ - 10
114
+ - 2
93
115
  version: 2.10.2
94
- version:
116
+ type: :runtime
117
+ version_requirements: *id007
95
118
  - !ruby/object:Gem::Dependency
96
119
  name: fast_gettext
97
- type: :runtime
98
- version_requirement:
99
- version_requirements: !ruby/object:Gem::Requirement
120
+ prerelease: false
121
+ requirement: &id008 !ruby/object:Gem::Requirement
100
122
  requirements:
101
123
  - - ~>
102
124
  - !ruby/object:Gem::Version
125
+ segments:
126
+ - 0
127
+ - 4
128
+ - 16
103
129
  version: 0.4.16
104
- version:
105
- - !ruby/object:Gem::Dependency
106
- name: delayed_job
107
130
  type: :runtime
108
- version_requirement:
109
- version_requirements: !ruby/object:Gem::Requirement
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: 1.8.4
114
- version:
131
+ version_requirements: *id008
115
132
  - !ruby/object:Gem::Dependency
116
133
  name: syntax
117
- type: :runtime
118
- version_requirement:
119
- version_requirements: !ruby/object:Gem::Requirement
134
+ prerelease: false
135
+ requirement: &id009 !ruby/object:Gem::Requirement
120
136
  requirements:
121
137
  - - "="
122
138
  - !ruby/object:Gem::Version
139
+ segments:
140
+ - 1
141
+ - 0
142
+ - 0
123
143
  version: 1.0.0
124
- version:
144
+ type: :runtime
145
+ version_requirements: *id009
125
146
  - !ruby/object:Gem::Dependency
126
147
  name: yamltest
127
- type: :runtime
128
- version_requirement:
129
- version_requirements: !ruby/object:Gem::Requirement
148
+ prerelease: false
149
+ requirement: &id010 !ruby/object:Gem::Requirement
130
150
  requirements:
131
151
  - - ">="
132
152
  - !ruby/object:Gem::Version
153
+ segments:
154
+ - 0
155
+ - 5
156
+ - 3
133
157
  version: 0.5.3
134
- version:
135
- - !ruby/object:Gem::Dependency
136
- name: thinking-sphinx
137
158
  type: :runtime
138
- version_requirement:
139
- version_requirements: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - ">="
142
- - !ruby/object:Gem::Version
143
- version: 1.3.14
144
- version:
159
+ version_requirements: *id010
145
160
  - !ruby/object:Gem::Dependency
146
161
  name: json
147
- type: :runtime
148
- version_requirement:
149
- version_requirements: !ruby/object:Gem::Requirement
162
+ prerelease: false
163
+ requirement: &id011 !ruby/object:Gem::Requirement
150
164
  requirements:
151
165
  - - ">="
152
166
  - !ruby/object:Gem::Version
167
+ segments:
168
+ - 1
169
+ - 1
170
+ - 9
153
171
  version: 1.1.9
154
- version:
172
+ type: :runtime
173
+ version_requirements: *id011
155
174
  - !ruby/object:Gem::Dependency
156
175
  name: will_paginate
157
- type: :runtime
158
- version_requirement:
159
- version_requirements: !ruby/object:Gem::Requirement
176
+ prerelease: false
177
+ requirement: &id012 !ruby/object:Gem::Requirement
160
178
  requirements:
161
179
  - - ~>
162
180
  - !ruby/object:Gem::Version
181
+ segments:
182
+ - 2
183
+ - 3
184
+ - 12
163
185
  version: 2.3.12
164
- version:
186
+ type: :runtime
187
+ version_requirements: *id012
165
188
  - !ruby/object:Gem::Dependency
166
189
  name: gettext
167
- type: :runtime
168
- version_requirement:
169
- version_requirements: !ruby/object:Gem::Requirement
190
+ prerelease: false
191
+ requirement: &id013 !ruby/object:Gem::Requirement
170
192
  requirements:
171
- - - "="
193
+ - - ">="
172
194
  - !ruby/object:Gem::Version
195
+ segments:
196
+ - 1
197
+ - 93
198
+ - 0
173
199
  version: 1.93.0
174
- version:
200
+ type: :runtime
201
+ version_requirements: *id013
175
202
  - !ruby/object:Gem::Dependency
176
203
  name: jeweler
177
- type: :runtime
178
- version_requirement:
179
- version_requirements: !ruby/object:Gem::Requirement
204
+ prerelease: false
205
+ requirement: &id014 !ruby/object:Gem::Requirement
180
206
  requirements:
181
207
  - - ">="
182
208
  - !ruby/object:Gem::Version
209
+ segments:
210
+ - 0
183
211
  version: "0"
184
- version:
185
- - !ruby/object:Gem::Dependency
186
- name: rmagick
187
212
  type: :runtime
188
- version_requirement:
189
- version_requirements: !ruby/object:Gem::Requirement
190
- requirements:
191
- - - ">="
192
- - !ruby/object:Gem::Version
193
- version: 2.10.0
194
- version:
213
+ version_requirements: *id014
195
214
  - !ruby/object:Gem::Dependency
196
215
  name: hpricot
197
- type: :runtime
198
- version_requirement:
199
- version_requirements: !ruby/object:Gem::Requirement
216
+ prerelease: false
217
+ requirement: &id015 !ruby/object:Gem::Requirement
200
218
  requirements:
201
219
  - - ">="
202
220
  - !ruby/object:Gem::Version
221
+ segments:
222
+ - 0
203
223
  version: "0"
204
- version:
224
+ type: :runtime
225
+ version_requirements: *id015
205
226
  - !ruby/object:Gem::Dependency
206
227
  name: differ
207
- type: :runtime
208
- version_requirement:
209
- version_requirements: !ruby/object:Gem::Requirement
228
+ prerelease: false
229
+ requirement: &id016 !ruby/object:Gem::Requirement
210
230
  requirements:
211
231
  - - ">="
212
232
  - !ruby/object:Gem::Version
233
+ segments:
234
+ - 0
235
+ - 1
236
+ - 1
213
237
  version: 0.1.1
214
- version:
238
+ type: :runtime
239
+ version_requirements: *id016
215
240
  - !ruby/object:Gem::Dependency
216
241
  name: RedCloth
217
- type: :runtime
218
- version_requirement:
219
- version_requirements: !ruby/object:Gem::Requirement
242
+ prerelease: false
243
+ requirement: &id017 !ruby/object:Gem::Requirement
220
244
  requirements:
221
245
  - - "="
222
246
  - !ruby/object:Gem::Version
247
+ segments:
248
+ - 3
249
+ - 0
250
+ - 4
223
251
  version: 3.0.4
224
- version:
252
+ type: :runtime
253
+ version_requirements: *id017
225
254
  - !ruby/object:Gem::Dependency
226
255
  name: querybuilder
227
- type: :runtime
228
- version_requirement:
229
- version_requirements: !ruby/object:Gem::Requirement
256
+ prerelease: false
257
+ requirement: &id018 !ruby/object:Gem::Requirement
230
258
  requirements:
231
259
  - - "="
232
260
  - !ruby/object:Gem::Version
261
+ segments:
262
+ - 0
263
+ - 5
264
+ - 8
233
265
  version: 0.5.8
234
- version:
266
+ type: :runtime
267
+ version_requirements: *id018
235
268
  description: zena is a Ruby on Rails CMS (content managment system) with a focus on usability, ease of customization and web 2.0 goodness (application like behaviour).
236
269
  email: gaspard@teti.ch
237
270
  executables:
@@ -2149,18 +2182,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
2149
2182
  requirements:
2150
2183
  - - ">="
2151
2184
  - !ruby/object:Gem::Version
2185
+ segments:
2186
+ - 0
2152
2187
  version: "0"
2153
- version:
2154
2188
  required_rubygems_version: !ruby/object:Gem::Requirement
2155
2189
  requirements:
2156
2190
  - - ">="
2157
2191
  - !ruby/object:Gem::Version
2192
+ segments:
2193
+ - 0
2158
2194
  version: "0"
2159
- version:
2160
2195
  requirements: []
2161
2196
 
2162
2197
  rubyforge_project: zena
2163
- rubygems_version: 1.3.5
2198
+ rubygems_version: 1.3.6
2164
2199
  signing_key:
2165
2200
  specification_version: 3
2166
2201
  summary: CMS with super natural powers, based on Ruby on Rails