cortex-reaver 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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