cortex-reaver 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/bin/cortex_reaver +9 -2
  2. data/lib/cortex_reaver.rb +61 -14
  3. data/lib/cortex_reaver/config.rb +6 -1
  4. data/lib/cortex_reaver/controller/journal.rb +3 -1
  5. data/lib/cortex_reaver/controller/main.rb +10 -9
  6. data/lib/cortex_reaver/controller/page.rb +4 -2
  7. data/lib/cortex_reaver/controller/photograph.rb +3 -1
  8. data/lib/cortex_reaver/controller/project.rb +1 -1
  9. data/lib/cortex_reaver/controller/tag.rb +1 -1
  10. data/lib/cortex_reaver/helper/canonical.rb +1 -1
  11. data/lib/cortex_reaver/helper/crud.rb +7 -15
  12. data/lib/cortex_reaver/helper/navigation.rb +16 -0
  13. data/lib/cortex_reaver/helper/pages.rb +62 -0
  14. data/lib/cortex_reaver/helper/tags.rb +2 -3
  15. data/lib/cortex_reaver/migrations/009_mysql.rb +8 -4
  16. data/lib/cortex_reaver/migrations/010_pageparents.rb +17 -0
  17. data/lib/cortex_reaver/model/page.rb +68 -7
  18. data/lib/cortex_reaver/plugin.rb +4 -0
  19. data/lib/cortex_reaver/public/css/main.css +4 -1
  20. data/lib/cortex_reaver/public/images/tag.gif +0 -0
  21. data/lib/cortex_reaver/public/js/autocompletefb.js +125 -0
  22. data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +1 -1
  23. data/lib/cortex_reaver/support/canonical.rb +42 -38
  24. data/lib/cortex_reaver/support/renderer.rb +10 -72
  25. data/lib/cortex_reaver/support/sequenceable.rb +1 -1
  26. data/lib/cortex_reaver/support/tags.rb +17 -6
  27. data/lib/cortex_reaver/version.rb +2 -2
  28. data/lib/cortex_reaver/view/journals/journal.rhtml +4 -3
  29. data/lib/cortex_reaver/view/pages/form.rhtml +1 -0
  30. data/lib/cortex_reaver/view/pages/list.rhtml +3 -3
  31. data/lib/cortex_reaver/view/pages/show.rhtml +2 -8
  32. data/lib/cortex_reaver/view/photographs/show.rhtml +1 -1
  33. data/lib/cortex_reaver/view/projects/show.rhtml +3 -2
  34. data/lib/cortex_reaver/view/tags/list.rhtml +4 -3
  35. data/lib/cortex_reaver/view/tags/show.rhtml +2 -2
  36. data/lib/cortex_reaver/view/text_layout.rhtml +12 -9
  37. data/lib/cortex_reaver/view/users/list.rhtml +2 -2
  38. metadata +11 -6
data/bin/cortex_reaver CHANGED
@@ -75,6 +75,11 @@ module CortexReaver
75
75
  @action = :start
76
76
  end
77
77
 
78
+ o.on '-t', '--test',
79
+ 'Run tests' do
80
+ @action = :test
81
+ end
82
+
78
83
  o.on '--status', 'Check Cortex Reaver status' do
79
84
  @action = :status
80
85
  end
@@ -162,7 +167,7 @@ module CortexReaver
162
167
  puts "Using database #{config[:database][:host]}/#{config[:database][:database]}."
163
168
 
164
169
  current_version = Sequel::Migrator.get_current_migration_version(db)
165
- latest_version = Sequel::Migrator.latest_migration_version(LIB_DIR/:migrations)
170
+ latest_version = Sequel::Migrator.latest_migration_version(File.join(LIB_DIR, 'migrations'))
166
171
 
167
172
  if version == current_version and current_version == latest_version
168
173
  puts "The database is already at the latest version (#{latest_version})."
@@ -182,7 +187,7 @@ module CortexReaver
182
187
 
183
188
  if confirm message
184
189
  puts "Migrating database from version #{current_version} to version #{version}..."
185
- Sequel::Migrator.apply(db, LIB_DIR/:migrations, version)
190
+ Sequel::Migrator.apply(db, File.join(LIB_DIR, 'migrations'), version)
186
191
  puts "Done."
187
192
  else
188
193
  exit
@@ -223,6 +228,8 @@ module CortexReaver
223
228
  when :stop
224
229
  stop
225
230
 
231
+ when :test
232
+ require File.join(DIR, '..', 'spec', 'main.rb')
226
233
  else
227
234
  abort("Unknown action: #{@action}")
228
235
  end
data/lib/cortex_reaver.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
3
  begin
4
+ require 'find'
4
5
  require 'rubygems'
5
6
  require 'ramaze'
6
7
  require 'sequel'
@@ -10,19 +11,19 @@ rescue LoadError => e
10
11
  puts e
11
12
  puts "You probably need to install some packages Cortex Reaver needs. Try:
12
13
  apt-get install librmagick-ruby libmysql-ruby;
13
- gem install mongrel ramaze sequel yaml erubis BlueCloth rmagick exifr hpricot builder syntax;"
14
+ gem install thin mongrel ramaze sequel yaml erubis BlueCloth rmagick exifr hpricot builder coderay;"
14
15
  exit 255
15
16
  end
16
17
 
17
18
  module CortexReaver
18
19
  # Paths
19
- ROOT = File.expand_path(__DIR__/'..')
20
- LIB_DIR = ROOT/:lib/:cortex_reaver
20
+ ROOT = File.expand_path(File.join(__DIR__, '..'))
21
+ LIB_DIR = File.join(ROOT, 'lib', 'cortex_reaver')
21
22
  HOME_DIR = Dir.pwd
22
23
 
23
24
  # Some basic initial requirements
24
- require LIB_DIR/:version
25
- require LIB_DIR/:config
25
+ require File.join(LIB_DIR, 'version')
26
+ require File.join(LIB_DIR, 'config')
26
27
 
27
28
  # Returns the site configuration
28
29
  def self.config
@@ -44,8 +45,8 @@ module CortexReaver
44
45
  # Prepare Ramaze, create directories, etc.
45
46
  def self.init
46
47
  # Tell Ramaze where to find public files and views
47
- Ramaze::Global.public_root = LIB_DIR/:public
48
- Ramaze::Global.view_root = config[:view_root]
48
+ Ramaze::Global.public_root = File.join(LIB_DIR, 'public')
49
+ Ramaze::Global.view_root = config[:view_root] || File.join(CortexReaver::LIB_DIR, 'view')
49
50
  Ramaze::Global.compile = config[:compile_views]
50
51
 
51
52
  # Check directories
@@ -111,17 +112,51 @@ module CortexReaver
111
112
  else
112
113
  raise ArgumentError.new("unknown Cortex Reaver mode #{config[:mode].inspect}. Expected one of [:production, :development].")
113
114
  end
115
+
116
+ # Prepare view directory
117
+ if config[:view_root]
118
+ if not File.directory? config[:view_root]
119
+ # Try to create a view directory
120
+ begin
121
+ FileUtils.mkdir_p config[:view_root]
122
+ rescue => e
123
+ Ramaze::Log.warn "Unable to create a view directory at #{config[:view_root]}: #{e}."
124
+ end
125
+ end
126
+
127
+ if File.directory? config[:view_root]
128
+ # Link in default views
129
+ source = File.join(LIB_DIR, 'view')
130
+ dest = config[:view_root].sub(/\/$/, '')
131
+ Find.find(source) do |path|
132
+ dest_path = path.sub(source, dest)
133
+ if File.directory? path and not File.exists? dest_path
134
+ # Link this directory
135
+ FileUtils.ln_s path, dest_path
136
+ Find.prune
137
+ elsif File.file? path and not File.exists? dest_path
138
+ FileUtils.ln_s path, dest_path
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ # Load plugins
145
+ config[:plugins].each do |plugin|
146
+ Ramaze::Log.info "Loading plugin #{plugin}"
147
+ require File.join(config[:plugin_root], plugin)
148
+ end
114
149
  end
115
150
 
116
151
  # Load libraries
117
152
  def self.load
118
153
  # Load controllers and models
119
- acquire LIB_DIR/:snippets/'**'/'*'
120
- acquire LIB_DIR/:support/'*'
121
- acquire LIB_DIR/:model/'*'
122
- acquire LIB_DIR/:helper/'*'
123
- acquire LIB_DIR/:controller/'*'
124
- acquire LIB_DIR/'**'/'*'
154
+ Ramaze::acquire File.join(LIB_DIR, 'snippets', '**', '*')
155
+ Ramaze::acquire File.join(LIB_DIR, 'support', '*')
156
+ Ramaze::acquire File.join(LIB_DIR, 'model', '*')
157
+ Ramaze::acquire File.join(LIB_DIR, 'helper', '*')
158
+ Ramaze::acquire File.join(LIB_DIR, 'controller', '*')
159
+ Ramaze::acquire File.join(LIB_DIR, '**', '*')
125
160
  end
126
161
 
127
162
  # Reloads the site configuration
@@ -144,6 +179,18 @@ module CortexReaver
144
179
  def self.run
145
180
  # Shutdown callback
146
181
  at_exit do
182
+ # Unlink templates
183
+ Find.find(config[:view_root]) do |path|
184
+ if File.symlink? path # TODO: identify link target
185
+ begin
186
+ File.delete path
187
+ rescue => e
188
+ Ramaze::Log.error "Unable to unlink symlinked view #{path}: #{e}"
189
+ end
190
+ end
191
+ end
192
+
193
+ # Remove pidfile
147
194
  FileUtils.rm(config[:pidfile]) if File.exist? config[:pidfile]
148
195
  end
149
196
 
@@ -195,7 +242,7 @@ module CortexReaver
195
242
  # Check schema
196
243
  if check_schema and
197
244
  Sequel::Migrator.get_current_migration_version(@db) !=
198
- Sequel::Migrator.latest_migration_version(LIB_DIR/:migrations)
245
+ Sequel::Migrator.latest_migration_version(File.join(LIB_DIR, 'migrations'))
199
246
 
200
247
  raise RuntimeError.new("database schema missing or out of date. Please run `cortex_reaver --migrate`.")
201
248
  end
@@ -11,6 +11,8 @@ module CortexReaver
11
11
  # Cortex Reaver's builtin templates.
12
12
  # :log_root - The directory that Cortex Reaver should log to. Defaults to
13
13
  # HOME_DIR/log. If nil, file logging disabled.
14
+ # :plugin_root - The directory that Cortex Reaver plugins live in. Defaults
15
+ # to HOME_DIR/plugins.
14
16
  # :mode - Cortex Reaver mode: either :development or :production
15
17
  # :daemon - Whether to daemonize or not. Defaults to :true if :mode
16
18
  # is :production, otherwise nil.
@@ -21,6 +23,7 @@ module CortexReaver
21
23
  # HOME_DIR/cortex_reaver_<host>_<port>.pid
22
24
  # :compile_views - Whether to cache compiled view templates. Defaults to
23
25
  # true in production mode.
26
+ # :plugins - Which plugins to enable. Defaults to [].
24
27
  #
25
28
  # Site configuration options
26
29
  # :site = {
@@ -36,12 +39,14 @@ module CortexReaver
36
39
  'cortex_reaver.db'
37
40
  )
38
41
  self[:public_root] = File.join(CortexReaver::HOME_DIR, 'public')
39
- self[:view_root] = File.join(CortexReaver::LIB_DIR, 'view')
42
+ self[:view_root] = nil
40
43
  self[:log_root] = File.join(CortexReaver::HOME_DIR, 'log')
44
+ self[:plugin_root] = File.join(CortexReaver::HOME_DIR, 'plugins')
41
45
  self[:mode] = :production
42
46
  self[:adapter] = 'thin'
43
47
  self[:host] = nil
44
48
  self[:port] = 7000
49
+ self[:plugins] = []
45
50
 
46
51
  self[:site] = {
47
52
  :name => 'Cortex Reaver',
@@ -27,11 +27,13 @@ module CortexReaver
27
27
  journal.tags = request[:tags]
28
28
  add_attachments(journal, request[:attachments])
29
29
  journal.body = request[:body]
30
+
31
+ MainController.send(:action_cache).clear
30
32
  end
31
33
 
32
34
  on_save do |journal, request|
33
35
  journal.title = request[:title]
34
- journal.name = Journal.canonicalize request[:name], journal.id
36
+ journal.name = Journal.canonicalize(request[:name], :id => journal.id)
35
37
  journal.user = session[:user]
36
38
  end
37
39
 
@@ -12,23 +12,24 @@ module CortexReaver
12
12
  :date,
13
13
  :tags,
14
14
  :form,
15
- :feeds
15
+ :feeds,
16
+ :pages
16
17
 
17
18
  engine :Erubis
18
19
 
19
20
  cache :index, :ttl => 60
20
21
 
21
22
  # the index action is called automatically when no other action is specified
22
- def index(id = nil)
23
- if id and @page = Page.get(id)
23
+ def index(*ids)
24
+ if not ids.empty? and @page = Page.get(ids)
24
25
  # Render that page.
25
26
  @title = @page.title
26
27
 
27
- workflow "Edit this page", R(PageController, :edit, @page.name)
28
- workflow "Delete this page", R(PageController, :delete, @page.name)
28
+ workflow "Edit this page", R(PageController, :edit, @page.id)
29
+ workflow "Delete this page", R(PageController, :delete, @page.id)
29
30
 
30
31
  render_template 'pages/show'
31
- elsif id
32
+ elsif not ids.empty?
32
33
  # Didn't have that page
33
34
  error_404
34
35
  else
@@ -41,10 +42,10 @@ module CortexReaver
41
42
  @sidebar.unshift render_template('photographs/sidebar.rhtml')
42
43
  end
43
44
 
44
- workflow "New Page", R(JournalController, :new)
45
- workflow "New Project", R(JournalController, :new)
46
45
  workflow "New Journal", R(JournalController, :new)
47
- workflow "New Photograph", R(JournalController, :new)
46
+ workflow "New Page", R(PageController, :new)
47
+ workflow "New Photograph", R(PhotographController, :new)
48
+ workflow "New Project", R(ProjectController, :new)
48
49
 
49
50
  feed 'Photographs', Rs(PhotographController, :atom)
50
51
  feed 'Journals', Rs(JournalController, :atom)
@@ -17,7 +17,8 @@ module CortexReaver
17
17
  :tags,
18
18
  :canonical,
19
19
  :crud,
20
- :attachments
20
+ :attachments,
21
+ :pages
21
22
 
22
23
  on_second_save do |page, request|
23
24
  page.tags = request[:tags]
@@ -26,7 +27,8 @@ module CortexReaver
26
27
 
27
28
  on_save do |page, request|
28
29
  page.title = request[:title]
29
- page.name = Page.canonicalize request[:name], page.id
30
+ page.page_id = request[:page_id]
31
+ page.name = Page.canonicalize request[:name], :id => page.id, :page_id => page.page_id
30
32
  page.body = request[:body]
31
33
  page.user = session[:user]
32
34
  end
@@ -30,7 +30,7 @@ module CortexReaver
30
30
 
31
31
  on_save do |photograph, request|
32
32
  photograph.title = request[:title]
33
- photograph.name = Photograph.canonicalize request[:name], photograph.id
33
+ photograph.name = Photograph.canonicalize request[:name], :id => photograph.id
34
34
  photograph.user = session[:user]
35
35
  end
36
36
 
@@ -38,6 +38,8 @@ module CortexReaver
38
38
  photograph.tags = request[:tags]
39
39
  photograph.image = request[:image][:tempfile] if request[:image]
40
40
  photograph.infer_date_from_exif! if request[:infer_date]
41
+
42
+ MainController.action_cache.clear
41
43
  end
42
44
 
43
45
  for_feed do |photograph, x|
@@ -31,7 +31,7 @@ module CortexReaver
31
31
  on_save do |project, request|
32
32
  project.title = request[:title]
33
33
  project.description = request[:description]
34
- project.name = Project.canonicalize request[:name], project.id
34
+ project.name = Project.canonicalize request[:name], :id => project.id
35
35
  project.body = request[:body]
36
36
  project.user = session[:user]
37
37
  end
@@ -22,7 +22,7 @@ module CortexReaver
22
22
 
23
23
  on_save do |tag, request|
24
24
  tag.title = request[:title]
25
- tag.name = Tag.canonicalize request[:name], tag.id
25
+ tag.name = Tag.canonicalize request[:name], :id => tag.id
26
26
  end
27
27
 
28
28
  def index(*ids)
@@ -7,7 +7,7 @@ module Ramaze
7
7
  def canonicalize
8
8
  respond self.class.const_get('MODEL').canonicalize(
9
9
  request[:new],
10
- request[:id]
10
+ :id => request[:id]
11
11
  )
12
12
  end
13
13
 
@@ -176,7 +176,7 @@ module Ramaze
176
176
  def delete(id)
177
177
  require_admin
178
178
 
179
- if @model = model_class.get(id)
179
+ if @model = model_class[id]
180
180
  if @model.destroy
181
181
  flash[:notice] = "#{model_class.to_s.demodulize.downcase} #{h @model.to_s} deleted."
182
182
  redirect Rs()
@@ -193,13 +193,9 @@ module Ramaze
193
193
  def edit(id = nil)
194
194
  require_admin
195
195
 
196
- if @model = model_class.get(id)
196
+ if @model = model_class[id]
197
197
  @title = "Edit #{model_class.to_s.demodulize.downcase} #{h @model.to_s}"
198
- if @model.class.respond_to? :canonical_name_attr
199
- @form_action = "edit/#{@model.send(@model.class.canonical_name_attr)}"
200
- else
201
- @form_action = "edit/#{@model.id}"
202
- end
198
+ @form_action = "edit/#{@model.id}"
203
199
 
204
200
  set_singular_model_var @model
205
201
 
@@ -245,7 +241,6 @@ module Ramaze
245
241
  end
246
242
 
247
243
  def page(page)
248
-
249
244
  page = case page
250
245
  when Symbol
251
246
  page
@@ -303,14 +298,11 @@ module Ramaze
303
298
  end
304
299
 
305
300
  # ID component of edit/delete links
306
- if @model.class.respond_to? :canonical_name_attr
307
- id = @model.send(@model.class.canonical_name_attr)
308
- else
309
- id = @model.id
310
- end
311
301
 
312
- workflow "Edit this #{model_class.to_s.demodulize}", Rs(:edit, id)
313
- workflow "Delete this #{model_class.to_s.demodulize}", Rs(:delete, id)
302
+ workflow "New #{model_class.to_s.demodulize}", Rs(:new)
303
+ workflow "Edit this #{model_class.to_s.demodulize}", Rs(:edit, @model.id)
304
+ workflow "Delete this #{model_class.to_s.demodulize}", Rs(:delete, @model.id)
305
+
314
306
  render_template :show
315
307
  elsif id
316
308
  # Didn't find that model
@@ -104,6 +104,22 @@ module Ramaze
104
104
  links << '</ol>'
105
105
  end
106
106
 
107
+ # Produces a section navigation list from an array of titles to urls.
108
+ def section_nav(sections)
109
+ s = "<ul>\n"
110
+ sections.each do |section|
111
+ title = section.first
112
+ url = section.last
113
+ klass = url.gsub(/\//, '').gsub(/_/, '-')
114
+ s << '<li><a class="' + klass
115
+ s << ' selected' if request.request_uri == url
116
+ s << '" href="' + attr_h(url) + '">'
117
+ s << title
118
+ s << "</a></li>\n"
119
+ end
120
+ s << "\n</ul>"
121
+ end
122
+
107
123
  # Returns a link to a user.
108
124
  def user_link(x)
109
125
  case x
@@ -0,0 +1,62 @@
1
+ module Ramaze
2
+ module Helper
3
+ module Pages
4
+ # Gives a list of lists showing page heirarchy navigation. Expands to show
5
+ # the current page if given.
6
+ def page_navigation(current=nil)
7
+ l = "<ol>\n"
8
+ CortexReaver::Page.top.all.each do |page|
9
+ l << page_navigation_helper(page, current)
10
+ end
11
+ l << '</ol>'
12
+ end
13
+
14
+ def page_navigation_helper(page, current=nil)
15
+ l = '<li' + (page == current ? ' class="selected"' : '') + '>'
16
+ l << "<a href=\"#{page.url}\">#{h page.title}</a>"
17
+ if page.pages and current.within? page
18
+ l << "\n<ol>"
19
+ page.pages.each do |page|
20
+ l << page_navigation_helper(page, current)
21
+ end
22
+ l << "</ol>\n"
23
+ end
24
+ l << "</li>\n"
25
+ end
26
+
27
+ # Returns a page selector
28
+ def page_select(id, params={})
29
+ type = params[:type]
30
+ p_class = params[:p_class]
31
+ description = params[:description] || id.to_s.titleize
32
+ model = params[:model]
33
+ default_id = params[:default_id]
34
+ skip_id = params[:skip_id]
35
+
36
+ f = "<p #{p_class.nil? ? '' : 'class="' + attr_h(p_class) + '"'}>"
37
+ f << "<label for=\"#{id}\">#{description}</label>"
38
+ f << "<select name=\"#{id}\" id=\"#{id}\">"
39
+ f << "<option value="">/</option>"
40
+ CortexReaver::Page.top.order(:title).all.each do |page|
41
+ f << page_select_helper(page, default_id, skip_id)
42
+ end
43
+ f << "</select></p>"
44
+ end
45
+
46
+ private
47
+
48
+ def page_select_helper(page, default_id=nil, skip_id=nil, depth=0)
49
+ s = '<option' +
50
+ (page.id == default_id ? ' selected="selected"' : '') +
51
+ (page.id == skip_id ? ' disabled="disabled"' : '') +
52
+ " value=\"#{page.id}\">" +
53
+ '&nbsp;&nbsp;' * depth +
54
+ "#{h page.title}</option>\n"
55
+ page.pages_dataset.order(:title).all.each do |page|
56
+ s << page_select_helper(page, default_id, skip_id, depth + 1)
57
+ end
58
+ s
59
+ end
60
+ end
61
+ end
62
+ end