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