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.
- data/bin/cortex_reaver +9 -2
- data/lib/cortex_reaver.rb +61 -14
- data/lib/cortex_reaver/config.rb +6 -1
- data/lib/cortex_reaver/controller/journal.rb +3 -1
- data/lib/cortex_reaver/controller/main.rb +10 -9
- data/lib/cortex_reaver/controller/page.rb +4 -2
- data/lib/cortex_reaver/controller/photograph.rb +3 -1
- data/lib/cortex_reaver/controller/project.rb +1 -1
- data/lib/cortex_reaver/controller/tag.rb +1 -1
- data/lib/cortex_reaver/helper/canonical.rb +1 -1
- data/lib/cortex_reaver/helper/crud.rb +7 -15
- data/lib/cortex_reaver/helper/navigation.rb +16 -0
- data/lib/cortex_reaver/helper/pages.rb +62 -0
- data/lib/cortex_reaver/helper/tags.rb +2 -3
- data/lib/cortex_reaver/migrations/009_mysql.rb +8 -4
- data/lib/cortex_reaver/migrations/010_pageparents.rb +17 -0
- data/lib/cortex_reaver/model/page.rb +68 -7
- data/lib/cortex_reaver/plugin.rb +4 -0
- data/lib/cortex_reaver/public/css/main.css +4 -1
- data/lib/cortex_reaver/public/images/tag.gif +0 -0
- data/lib/cortex_reaver/public/js/autocompletefb.js +125 -0
- data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +1 -1
- data/lib/cortex_reaver/support/canonical.rb +42 -38
- data/lib/cortex_reaver/support/renderer.rb +10 -72
- data/lib/cortex_reaver/support/sequenceable.rb +1 -1
- data/lib/cortex_reaver/support/tags.rb +17 -6
- data/lib/cortex_reaver/version.rb +2 -2
- data/lib/cortex_reaver/view/journals/journal.rhtml +4 -3
- data/lib/cortex_reaver/view/pages/form.rhtml +1 -0
- data/lib/cortex_reaver/view/pages/list.rhtml +3 -3
- data/lib/cortex_reaver/view/pages/show.rhtml +2 -8
- data/lib/cortex_reaver/view/photographs/show.rhtml +1 -1
- data/lib/cortex_reaver/view/projects/show.rhtml +3 -2
- data/lib/cortex_reaver/view/tags/list.rhtml +4 -3
- data/lib/cortex_reaver/view/tags/show.rhtml +2 -2
- data/lib/cortex_reaver/view/text_layout.rhtml +12 -9
- data/lib/cortex_reaver/view/users/list.rhtml +2 -2
- 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
|
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
|
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
|
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
|
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
|
25
|
-
require LIB_DIR
|
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
|
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
|
120
|
-
acquire LIB_DIR
|
121
|
-
acquire LIB_DIR
|
122
|
-
acquire LIB_DIR
|
123
|
-
acquire LIB_DIR
|
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
|
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
|
data/lib/cortex_reaver/config.rb
CHANGED
@@ -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] =
|
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
|
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(
|
23
|
-
if
|
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.
|
28
|
-
workflow "Delete this page", R(PageController, :delete, @page.
|
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
|
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
|
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.
|
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
|
@@ -176,7 +176,7 @@ module Ramaze
|
|
176
176
|
def delete(id)
|
177
177
|
require_admin
|
178
178
|
|
179
|
-
if @model = model_class
|
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
|
196
|
+
if @model = model_class[id]
|
197
197
|
@title = "Edit #{model_class.to_s.demodulize.downcase} #{h @model.to_s}"
|
198
|
-
|
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 "
|
313
|
-
workflow "
|
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
|
+
' ' * 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
|