cortex-reaver 0.0.6 → 0.0.7

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 (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