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