cortex-reaver 0.0.9 → 0.1.0
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 +7 -2
- data/lib/cortex_reaver.rb +51 -71
- data/lib/cortex_reaver/config.rb +23 -7
- data/lib/cortex_reaver/controller/admin.rb +6 -8
- data/lib/cortex_reaver/controller/comment.rb +17 -17
- data/lib/cortex_reaver/controller/config.rb +3 -2
- data/lib/cortex_reaver/controller/controller.rb +22 -0
- data/lib/cortex_reaver/controller/documentation.rb +1 -3
- data/lib/cortex_reaver/controller/journal.rb +13 -12
- data/lib/cortex_reaver/controller/main.rb +36 -29
- data/lib/cortex_reaver/controller/page.rb +15 -11
- data/lib/cortex_reaver/controller/photograph.rb +21 -15
- data/lib/cortex_reaver/controller/project.rb +16 -13
- data/lib/cortex_reaver/controller/tag.rb +16 -14
- data/lib/cortex_reaver/controller/user.rb +11 -13
- data/lib/cortex_reaver/helper/attachments.rb +18 -12
- data/lib/cortex_reaver/helper/auth.rb +2 -2
- data/lib/cortex_reaver/helper/canonical.rb +2 -2
- data/lib/cortex_reaver/helper/crud.rb +78 -38
- data/lib/cortex_reaver/helper/feeds.rb +2 -5
- data/lib/cortex_reaver/helper/form.rb +1 -1
- data/lib/cortex_reaver/helper/navigation.rb +1 -1
- data/lib/cortex_reaver/helper/photographs.rb +12 -3
- data/lib/cortex_reaver/helper/template.rb +37 -0
- data/lib/cortex_reaver/{view/blank_layout.rhtml → layout/blank.rhtml} +1 -1
- data/lib/cortex_reaver/{view/text_layout.rhtml → layout/text.rhtml} +1 -1
- data/lib/cortex_reaver/migrations/013_draft.rb +17 -0
- data/lib/cortex_reaver/model/comment.rb +64 -53
- data/lib/cortex_reaver/model/journal.rb +23 -21
- data/lib/cortex_reaver/model/model.rb +9 -0
- data/lib/cortex_reaver/model/page.rb +24 -42
- data/lib/cortex_reaver/model/photograph.rb +17 -17
- data/lib/cortex_reaver/model/project.rb +21 -18
- data/lib/cortex_reaver/model/tag.rb +12 -8
- data/lib/cortex_reaver/model/user.rb +79 -41
- data/lib/cortex_reaver/public/css/main.css +4 -0
- data/lib/cortex_reaver/snippets/numeric.rb +15 -0
- data/lib/cortex_reaver/snippets/ramaze/cache/memcached.rb +14 -0
- data/lib/cortex_reaver/support/attachments.rb +113 -105
- data/lib/cortex_reaver/support/cached_rendering.rb +65 -62
- data/lib/cortex_reaver/support/canonical.rb +82 -85
- data/lib/cortex_reaver/support/comments.rb +57 -51
- data/lib/cortex_reaver/support/cortex_reaver_validation_helpers.rb +13 -0
- data/lib/cortex_reaver/support/sequenceable.rb +202 -203
- data/lib/cortex_reaver/support/tags.rb +103 -94
- data/lib/cortex_reaver/support/timestamps.rb +27 -21
- data/lib/cortex_reaver/support/viewable.rb +17 -0
- data/lib/cortex_reaver/version.rb +3 -3
- data/lib/cortex_reaver/view/admin/index.rhtml +2 -2
- data/lib/cortex_reaver/view/comments/comment.rhtml +4 -1
- data/lib/cortex_reaver/view/comments/list.rhtml +1 -1
- data/lib/cortex_reaver/view/comments/post_form.rhtml +1 -1
- data/lib/cortex_reaver/view/journals/form.rhtml +3 -1
- data/lib/cortex_reaver/view/journals/journal.rhtml +6 -4
- data/lib/cortex_reaver/view/journals/list.rhtml +2 -2
- data/lib/cortex_reaver/view/journals/show.rhtml +1 -1
- data/lib/cortex_reaver/view/pages/form.rhtml +2 -1
- data/lib/cortex_reaver/view/pages/list.rhtml +2 -2
- data/lib/cortex_reaver/view/pages/show.rhtml +1 -1
- data/lib/cortex_reaver/view/photographs/form.rhtml +7 -3
- data/lib/cortex_reaver/view/photographs/list.rhtml +1 -1
- data/lib/cortex_reaver/view/photographs/show.rhtml +7 -7
- data/lib/cortex_reaver/view/projects/form.rhtml +1 -0
- data/lib/cortex_reaver/view/projects/list.rhtml +3 -3
- data/lib/cortex_reaver/view/projects/show.rhtml +5 -2
- data/lib/cortex_reaver/view/tags/list.rhtml +6 -2
- data/lib/cortex_reaver/view/tags/show.rhtml +10 -5
- data/lib/cortex_reaver/view/users/form.rhtml +1 -1
- data/lib/cortex_reaver/view/users/list.rhtml +5 -2
- data/lib/cortex_reaver/view/users/login.rhtml +1 -1
- data/lib/cortex_reaver/view/users/show.rhtml +5 -1
- metadata +159 -149
- data/lib/cortex_reaver/public/dispatch.fcgi +0 -11
- data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +0 -37
- data/lib/cortex_reaver/support/pagination.rb +0 -38
- data/lib/cortex_reaver/view/error.rhtml +0 -72
- data/lib/cortex_reaver/view/photographs/short.rhtml +0 -3
@@ -1,78 +1,81 @@
|
|
1
|
-
|
2
|
-
module Model
|
1
|
+
require 'ostruct'
|
3
2
|
|
3
|
+
module Sequel
|
4
|
+
module Plugins
|
4
5
|
# On save, calls a special rendering method on configured attributes, and
|
5
6
|
# saves the results to their cache.
|
6
7
|
module CachedRendering
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
fields = render_fields.select do |k, v|
|
20
|
-
changed.include? k.to_sym
|
21
|
-
end
|
22
|
-
|
23
|
-
fields.each do |name, field|
|
24
|
-
# Render and cache
|
25
|
-
self[field.to] = self.send(field.with, self[name])
|
8
|
+
module ClassMethods
|
9
|
+
# Refreshes all records with cached fields.
|
10
|
+
def refresh_render_caches
|
11
|
+
# TODO: inefficient, but Model.each breaks Sequel in validation
|
12
|
+
# "commands out of sync"
|
13
|
+
all.each do |record|
|
14
|
+
# Mark all caching columns as changed, so the before_save hook
|
15
|
+
# processes them.
|
16
|
+
record.skip_timestamp_update = true
|
17
|
+
render_fields.keys.each do |column|
|
18
|
+
record.changed_columns << column
|
26
19
|
end
|
20
|
+
record.save
|
27
21
|
end
|
22
|
+
nil
|
23
|
+
end
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
25
|
+
# Assigns a field to cache
|
26
|
+
#
|
27
|
+
# render :body, :with => 'wikify', :to => 'cached_body'
|
28
|
+
#
|
29
|
+
# ... calls #wikify on the value of self.body, and stores the result
|
30
|
+
# in self.cached_body. :to defaults to the field name with _cache
|
31
|
+
# appended. :with defaults to :render.
|
32
|
+
def render(field, params = {})
|
33
|
+
# Assign parameters
|
34
|
+
params = {
|
35
|
+
:to => (field.to_s + '_cache').to_sym,
|
36
|
+
:with => :render
|
37
|
+
}.merge!(params)
|
38
|
+
|
39
|
+
# Store field
|
40
|
+
render_fields[field] = OpenStruct.new(params)
|
41
|
+
end
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
params = {
|
55
|
-
:to => (field.to_s + '_cache').to_sym,
|
56
|
-
:with => :render
|
57
|
-
}.merge!(params)
|
58
|
-
|
59
|
-
# Store field
|
60
|
-
render_fields[field] = OpenStruct.new(params)
|
61
|
-
end
|
43
|
+
def render_fields
|
44
|
+
@render_fields ||= {}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module InstanceMethods
|
49
|
+
# Before save, render all changed caching fields
|
50
|
+
def before_save
|
51
|
+
return false if super == false
|
62
52
|
|
63
|
-
|
64
|
-
|
53
|
+
# Get changed fields to render
|
54
|
+
if new?
|
55
|
+
changed = columns.map { |c| c.to_sym }
|
56
|
+
else
|
57
|
+
changed = changed_columns.map { |c| c.to_sym }
|
58
|
+
end
|
59
|
+
fields = render_fields.select do |k, v|
|
60
|
+
changed.include? k.to_sym
|
65
61
|
end
|
62
|
+
|
63
|
+
fields.each do |name, field|
|
64
|
+
# Render and cache
|
65
|
+
self[field.to] = self.send(field.with, self[name])
|
66
|
+
end
|
67
|
+
|
68
|
+
true
|
66
69
|
end
|
67
|
-
end
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
# Default renderer
|
72
|
+
def render(value)
|
73
|
+
value
|
74
|
+
end
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
+
def render_fields
|
77
|
+
self.class.render_fields
|
78
|
+
end
|
76
79
|
end
|
77
80
|
end
|
78
81
|
end
|
@@ -1,110 +1,107 @@
|
|
1
|
-
module
|
2
|
-
module
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
3
|
# Supports canonical, url-safe identifiers for records, inferred from other
|
4
4
|
# fields.
|
5
5
|
module Canonical
|
6
|
+
module ClassMethods
|
7
|
+
# The canonical name attribute
|
8
|
+
CANONICAL_NAME_ATTR = :name
|
9
|
+
# The attribute we infer the canonical name from, if not set.
|
10
|
+
CANONICAL_INFERENCE_ATTR = :title
|
6
11
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
# Canonical names which cannot be reserved.
|
13
|
+
def reserved_canonical_names
|
14
|
+
@reserved_canonical_names ||= []
|
15
|
+
end
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
17
|
+
def reserved_canonical_names=(names)
|
18
|
+
@reserved_canonical_names = names
|
19
|
+
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
21
|
+
# Canonicalize a string. Optionally, ignore conflicts with the record
|
22
|
+
# with opts[:id]
|
23
|
+
def canonicalize(string, opts={})
|
24
|
+
# Lower case, remove special chars, and replace with hyphens.
|
25
|
+
proper = formalize string
|
23
26
|
|
24
|
-
|
25
|
-
|
27
|
+
# If proper is blank, just return it at this point.
|
28
|
+
if proper.blank?
|
29
|
+
return proper
|
26
30
|
end
|
27
31
|
|
28
|
-
#
|
29
|
-
|
30
|
-
def self.canonicalize(string, opts={})
|
31
|
-
# Lower case, remove special chars, and replace with hyphens.
|
32
|
-
proper = Canonical.formalize string
|
33
|
-
|
34
|
-
# If proper is blank, just return it at this point.
|
35
|
-
if proper.blank?
|
36
|
-
return proper
|
37
|
-
end
|
38
|
-
|
39
|
-
# Numeric suffix to append
|
40
|
-
suffix = nil
|
32
|
+
# Numeric suffix to append
|
33
|
+
suffix = nil
|
41
34
|
|
42
|
-
|
43
|
-
|
35
|
+
# Get similar names from the class
|
36
|
+
similar = similar_canonical_names(proper, opts)
|
44
37
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
38
|
+
# Get reserved names from the class
|
39
|
+
reserved_canonical_names.each do |name|
|
40
|
+
if name =~ /^#{proper}(-\d+)?$/
|
41
|
+
similar << name
|
50
42
|
end
|
43
|
+
end
|
51
44
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
45
|
+
# Extract numeric suffices
|
46
|
+
suffices = {}
|
47
|
+
similar.each do |name|
|
48
|
+
suffices[name[/\d$/].to_i] = true
|
49
|
+
end
|
57
50
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
suffix = i
|
65
|
-
end
|
66
|
-
|
67
|
-
# Apply suffix
|
68
|
-
if suffix
|
69
|
-
proper + '-' + suffix.to_s
|
70
|
-
else
|
71
|
-
proper
|
51
|
+
# Compute suffix
|
52
|
+
unless suffices.empty?
|
53
|
+
i = 1
|
54
|
+
while suffices.include? i
|
55
|
+
i += 1
|
72
56
|
end
|
57
|
+
suffix = i
|
58
|
+
end
|
59
|
+
|
60
|
+
# Apply suffix
|
61
|
+
if suffix
|
62
|
+
proper + '-' + suffix.to_s
|
63
|
+
else
|
64
|
+
proper
|
73
65
|
end
|
66
|
+
end
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
68
|
+
# Sets the attribute we infer the canonical name from to attr, or
|
69
|
+
# gets that attr if nil.
|
70
|
+
def canonical_inference_attr(attr = nil)
|
71
|
+
if attr
|
72
|
+
@canonical_inference_attr = attr.to_sym
|
73
|
+
else
|
74
|
+
@canonical_inference_attr || CANONICAL_INFERENCE_ATTR
|
83
75
|
end
|
76
|
+
end
|
84
77
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
78
|
+
# Sets the canonical name attribute to attr. Returns it if nil.
|
79
|
+
def canonical_name_attr(attr = nil)
|
80
|
+
if attr
|
81
|
+
@canonical_name_attr = attr.to_sym
|
82
|
+
else
|
83
|
+
@canonical_name_attr || CANONICAL_NAME_ATTR
|
92
84
|
end
|
85
|
+
end
|
93
86
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
def self.similar_canonical_names(proper, opts={})
|
98
|
-
id = opts[:id]
|
99
|
-
similar = []
|
100
|
-
if filter(canonical_name_attr => proper).exclude(:id => id).limit(1).count > 0
|
101
|
-
# This name already exists, and it's not ours.
|
102
|
-
similar << proper
|
103
|
-
similar += filter(canonical_name_attr.like(/^#{proper}\-[0-9]+$/)).map(canonical_name_attr)
|
104
|
-
end
|
105
|
-
similar
|
106
|
-
end
|
87
|
+
# Lower case, remove special chars, and replace with hyphens.
|
88
|
+
def formalize(string)
|
89
|
+
string.downcase.gsub(/'"/, '').gsub(/[^a-z0-9_]/, '-').squeeze('-')[0..250].sub(/-$/, '')
|
107
90
|
end
|
91
|
+
|
92
|
+
# Canonicalize only in the context of our parent's namespace. Takes a
|
93
|
+
# proper canonical name to check for conflicts with, and an optional id
|
94
|
+
# to ignore conflicts with
|
95
|
+
def similar_canonical_names(proper, opts={})
|
96
|
+
id = opts[:id]
|
97
|
+
similar = []
|
98
|
+
if filter(canonical_name_attr => proper).exclude(:id => id).limit(1).count > 0
|
99
|
+
# This name already exists, and it's not ours.
|
100
|
+
similar << proper
|
101
|
+
similar += filter(canonical_name_attr.like(/^#{proper}\-[0-9]+$/)).map(canonical_name_attr)
|
102
|
+
end
|
103
|
+
similar
|
104
|
+
end
|
108
105
|
end
|
109
106
|
end
|
110
107
|
end
|
@@ -1,67 +1,73 @@
|
|
1
|
-
module
|
2
|
-
module
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
3
|
# Support methods for comments on models
|
4
4
|
module Comments
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
remove_all_comments
|
11
|
-
comments.each do |comment|
|
12
|
-
comment.destroy
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# Refresh all comment counts
|
17
|
-
def self.refresh_comment_counts
|
18
|
-
all.each do |model|
|
19
|
-
model.refresh_comment_count
|
20
|
-
end
|
5
|
+
module ClassMethods
|
6
|
+
# Refresh all comment counts
|
7
|
+
def refresh_comment_counts
|
8
|
+
all.each do |model|
|
9
|
+
model.refresh_comment_count
|
21
10
|
end
|
22
11
|
end
|
23
12
|
end
|
24
13
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
14
|
+
module InstanceMethods
|
15
|
+
# When we delete a model that has comments, remove the comments too.
|
16
|
+
def before_destroy
|
17
|
+
Ramaze::Log.debug 'remove_comments'
|
18
|
+
return false if super == false
|
19
|
+
Ramaze::Log.debug 'removing comments'
|
20
|
+
|
21
|
+
comments = self.comments
|
22
|
+
remove_all_comments
|
23
|
+
comments.each do |comment|
|
24
|
+
comment.destroy
|
25
|
+
end
|
26
|
+
|
27
|
+
true
|
33
28
|
end
|
34
|
-
self[:comment_count] = count
|
35
|
-
self.skip_timestamp_update = true
|
36
29
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
30
|
+
# Recalculates the number of comments on this record (and all comments
|
31
|
+
# below it, recursively) and saves those values. Returns the comment
|
32
|
+
# count on this record.
|
33
|
+
def refresh_comment_count
|
34
|
+
count = 0
|
35
|
+
comments.each do |comment|
|
36
|
+
# Recalculate for sub-comments and sum.
|
37
|
+
count += comment.refresh_comment_count + 1
|
38
|
+
end
|
39
|
+
self[:comment_count] = count
|
40
|
+
self.skip_timestamp_update = true
|
41
|
+
|
42
|
+
# Save and return
|
43
|
+
self.save
|
44
|
+
self[:comment_count]
|
45
|
+
end
|
41
46
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
# Returns the parent of a given comment. Caches, pass true to refresh.
|
48
|
+
def parent(refresh = false)
|
49
|
+
if refresh or @parent_cache.nil?
|
50
|
+
[:comment, :journal, :photograph, :project, :page].each do |p|
|
51
|
+
if self.respond_to?(p) and parent = self.send(p)
|
52
|
+
# We found an applicable parent.
|
53
|
+
@parent_cache = parent
|
54
|
+
return parent
|
55
|
+
end
|
50
56
|
end
|
57
|
+
# We didn't find any parent
|
58
|
+
nil
|
59
|
+
else
|
60
|
+
@parent_cache
|
51
61
|
end
|
52
|
-
# We didn't find any parent
|
53
|
-
nil
|
54
|
-
else
|
55
|
-
@parent_cache
|
56
62
|
end
|
57
|
-
end
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
# Returns the top-level parent of a given comment.
|
65
|
+
def root_parent
|
66
|
+
if parent
|
67
|
+
parent.root_parent
|
68
|
+
else
|
69
|
+
self
|
70
|
+
end
|
65
71
|
end
|
66
72
|
end
|
67
73
|
end
|