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
@@ -0,0 +1,13 @@
1
+ module Sequel
2
+ module Plugins
3
+ # Extra validation helpers!
4
+ module CortexReaverValidationHelpers
5
+ module InstanceMethods
6
+ # Checks to ensure att and att_confirmation are the same.
7
+ def validates_confirmation(atts, opts={})
8
+ validatable_attributes(atts, opts) { |a,v,m| (m || "does not match confirmation") unless v == self.send(a.to_s + '_confirmation') }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,247 +1,246 @@
1
- module CortexReaver
2
- module Model
3
- # Sequences are models that have order. This module provides class
4
- # and instance methods that support sequential behavior like pagination, finding
5
- # the next or previoud record, and finding a "window" of results around a
6
- # specific record.
7
-
1
+ module Sequel
2
+ module Plugins
3
+ # Sequences are models that have order. This module provides class and
4
+ # instance methods that support sequential behavior like pagination,
5
+ # finding the next or previoud record, and finding a "window" of results
6
+ # around a specific record.
8
7
  module Sequenceable
9
8
 
10
- # Which column table to order this sequence by
11
- DEFAULT_SEQUENCE_ORDER = :created_on
12
- DEFAULT_SEQUENCE_REVERSE = false
13
- DEFAULT_WINDOW_SIZE = 16
14
-
15
9
  # Class methods
16
- def self.included(base)
17
- base.instance_eval do
18
- attr_writer :sequence_order, :sequence_reverse, :window_size
19
-
20
- # Returns the sequence dataset (optionally, restricted to dataset)
21
- def sequence(dataset = self.dataset)
22
- if sequence_reverse
23
- dataset.reverse_order(sequence_order)
24
- else
25
- dataset.order(sequence_order)
26
- end
10
+ module ClassMethods
11
+ # Which column table to order this sequence by
12
+ DEFAULT_SEQUENCE_ORDER = :created_on
13
+ DEFAULT_SEQUENCE_REVERSE = false
14
+ DEFAULT_WINDOW_SIZE = 16
15
+
16
+ # Returns the sequence dataset (optionally, restricted to dataset)
17
+ def sequence(dataset = self.dataset)
18
+ if sequence_reverse
19
+ dataset.reverse_order(sequence_order)
20
+ else
21
+ dataset.order(sequence_order)
27
22
  end
23
+ end
28
24
 
29
- # Returns the first record in the sequence
30
- def first
31
- sequence.first
32
- end
25
+ # Returns the first record in the sequence
26
+ def first
27
+ sequence.first
28
+ end
33
29
 
34
- # Returns the last record in the sequence
35
- def last
36
- sequence.last
37
- end
30
+ # Returns the last record in the sequence
31
+ def last
32
+ sequence.last
33
+ end
38
34
 
39
- # Returns the table column to order by
40
- def sequence_order
41
- @sequence_order || DEFAULT_SEQUENCE_ORDER
42
- end
35
+ # Returns the table column to order by
36
+ def sequence_order
37
+ @sequence_order || DEFAULT_SEQUENCE_ORDER
38
+ end
43
39
 
44
- # Sets the table column to order by
45
- def sequence_order=(order)
46
- @sequence_order = order
47
- end
40
+ # Sets the table column to order by
41
+ def sequence_order=(order)
42
+ @sequence_order = order
43
+ end
48
44
 
49
- # Returns whether or not to reverse the order
50
- def sequence_reverse
51
- @sequence_reverse || DEFAULT_SEQUENCE_REVERSE
52
- end
45
+ # Returns whether or not to reverse the order
46
+ def sequence_reverse
47
+ @sequence_reverse || DEFAULT_SEQUENCE_REVERSE
48
+ end
53
49
 
54
- # Sets whether to reverse the sequence
55
- def sequence_reverse=(reverse)
56
- @sequence_reverse = reverse
57
- end
50
+ # Sets whether to reverse the sequence
51
+ def sequence_reverse=(reverse)
52
+ @sequence_reverse = reverse
53
+ end
58
54
 
59
- # Returns an absolute window into this sequence, specified as an offset in
60
- # window-sized increments from the beginning of the sequence. Hence
61
- # window(0, 10) returns the first ten records in the sequence, window(1, 10)
62
- # the next ten, and so on.
63
- #
64
- # One can also specify the special page_offsets :first or :last, which
65
- # return the first and last available windows.
66
- def window(page_offset, size = self.window_size)
67
- case page_offset
68
- when :first
69
- page_offset = 0
70
- when :last
71
- page_offset = window_count(size) - 1
72
- else
73
- page_offset = page_offset.to_i
74
- end
55
+ # Returns an absolute window into this sequence, specified as an
56
+ # offset in window-sized increments from the beginning of the
57
+ # sequence. Hence window(0, 10) returns the first ten records in the
58
+ # sequence, window(1, 10) the next ten, and so on.
59
+ #
60
+ # One can also specify the special page_offsets :first or :last,
61
+ # which return the first and last available windows.
62
+ def window(page_offset, size = self.window_size)
63
+ case page_offset
64
+ when :first
65
+ page_offset = 0
66
+ when :last
67
+ page_offset = window_count(size) - 1
68
+ else
69
+ page_offset = page_offset.to_i
70
+ end
75
71
 
76
- # Don't ask for negative pages!
77
- page_offset = 0 if page_offset < 0
72
+ # Don't ask for negative pages!
73
+ page_offset = 0 if page_offset < 0
78
74
 
79
- # Calculate offset
80
- offset = page_offset * size
75
+ # Calculate offset
76
+ offset = page_offset * size
81
77
 
82
- # Limit dataset
83
- sequence.limit size, offset
84
- end
78
+ # Limit dataset
79
+ sequence.limit size, offset
80
+ end
85
81
 
86
- # Returns the number of windows required to span this sequence
87
- def window_count(size = self.window_size)
88
- (Float(sequence.count) / size).ceil
89
- end
82
+ # Returns the number of windows required to span this sequence
83
+ def window_count(size = self.window_size)
84
+ (Float(sequence.count) / size).ceil
85
+ end
90
86
 
91
- # Returns the size of a window into this sequence
92
- def window_size
93
- @window_size || DEFAULT_WINDOW_SIZE
94
- end
87
+ # Returns the size of a window into this sequence
88
+ def window_size
89
+ @window_size || DEFAULT_WINDOW_SIZE
90
+ end
95
91
 
96
- # Sets the size of a window into this sequence
97
- def window_size=(size)
98
- @window_size = size
99
- end
92
+ # Sets the size of a window into this sequence
93
+ def window_size=(size)
94
+ @window_size = size
100
95
  end
101
96
  end
102
97
 
103
- # Instance methods
98
+ module InstanceMethods
104
99
 
105
- # Convenience references to class methods
106
- def sequence
107
- self.class.sequence
108
- end
100
+ # Convenience references to class methods
101
+ def sequence
102
+ self.class.sequence
103
+ end
109
104
 
110
- def sequence_order
111
- self.class.sequence_order
112
- end
105
+ def sequence_order
106
+ self.class.sequence_order
107
+ end
113
108
 
114
- def sequence_reverse
115
- self.class.sequence_reverse
116
- end
109
+ def sequence_reverse
110
+ self.class.sequence_reverse
111
+ end
117
112
 
118
- # Returns the next record in the sequence. Caches--use next(true) to refresh.
119
- def next(refresh_cache = false)
120
- if refresh_cache
121
- @next = sequence.filter(sequence_order > send(sequence_order)).limit(1).first
122
- else
123
- @next ||= sequence.filter(sequence_order > send(sequence_order)).limit(1).first
113
+ # Returns the next record in the sequence. Caches--use next(true) to
114
+ # refresh.
115
+ def next(refresh_cache = false)
116
+ if refresh_cache
117
+ @next = sequence.filter(sequence_order > send(sequence_order)).limit(1).first
118
+ else
119
+ @next ||= sequence.filter(sequence_order > send(sequence_order)).limit(1).first
120
+ end
124
121
  end
125
- end
126
122
 
127
- # Returns true if a next record exists. Caches--use next(true) to refresh.
128
- def next?(refresh_cache = false)
129
- if refresh_cache
130
- @next_exists ||= self.next_count > 0 ? true : false
131
- else
132
- @next_exists = self.next_count > 0 ? true : false
123
+ # Returns true if a next record exists. Caches--use next(true) to
124
+ # refresh.
125
+ def next?(refresh_cache = false)
126
+ if refresh_cache
127
+ @next_exists ||= self.next_count > 0 ? true : false
128
+ else
129
+ @next_exists = self.next_count > 0 ? true : false
130
+ end
131
+ end
132
+
133
+ # Returns the number of succeeding records
134
+ def next_count
135
+ sequence.filter(sequence_order > send(sequence_order)).count
133
136
  end
134
- end
135
-
136
- # Returns the number of succeeding records
137
- def next_count
138
- sequence.filter(sequence_order > send(sequence_order)).count
139
- end
140
137
 
141
- # Returns the previous record in the sequence. Caches--use previous(true) to
142
- # refresh.
143
- def previous(refresh_cache = false)
144
- if refresh_cache
145
- @previous = sequence.filter(sequence_order < send(sequence_order)).reverse.limit(1).first
146
- else
147
- @previous ||= sequence.filter(sequence_order < send(sequence_order)).reverse.limit(1).first
148
- end
149
- end
138
+ # Returns the previous record in the sequence. Caches--use
139
+ # previous(true) to refresh.
140
+ def previous(refresh_cache = false)
141
+ if refresh_cache
142
+ @previous = sequence.filter(sequence_order < send(sequence_order)).reverse.limit(1).first
143
+ else
144
+ @previous ||= sequence.filter(sequence_order < send(sequence_order)).reverse.limit(1).first
145
+ end
146
+ end
150
147
 
151
- # Returns true if a previous record exists. Caches--use previous?(true) to
152
- # refresh.
153
- def previous?(refresh_cache = false)
154
- if refresh_cache
155
- @previous_exists = self.previous_count > 0 ? true : false
156
- else
157
- @previous_exists ||= self.previous_count > 0 ? true : false
148
+ # Returns true if a previous record exists. Caches--use previous?(true)
149
+ # to refresh.
150
+ def previous?(refresh_cache = false)
151
+ if refresh_cache
152
+ @previous_exists = self.previous_count > 0 ? true : false
153
+ else
154
+ @previous_exists ||= self.previous_count > 0 ? true : false
155
+ end
158
156
  end
159
- end
160
157
 
161
- # Returns the number of preceding records
162
- def previous_count
163
- sequence.filter(sequence_order < send(sequence_order)).count
164
- end
158
+ # Returns the number of preceding records
159
+ def previous_count
160
+ sequence.filter(sequence_order < send(sequence_order)).count
161
+ end
165
162
 
166
- alias :position :previous_count
167
-
168
- # Returns a collection of records around this record.
169
- # Mode is one of:
170
- # 1. :absolute Returns a window containing this record in even multiples from
171
- # the first record, like a page of a book.
172
- # 2. :float Returns a centered window of the provided size. If the edge of
173
- # the sequence is reached, the window shifts to include more
174
- # elements of the sequence. If no more elements are available
175
- # (the window is larger than the size of the sequence), the
176
- # entire sequence is returned. If the size is even, one more
177
- # record is returned suceeding this record than preceding this
178
- # record, if possible.
179
- # 3. :clip Returns a centered window of or smaller than the given size. If
180
- # the edge of the sequence is reached, the window is clipped.
181
- def window(mode = :absolute, size = self.class.window_size)
182
- case mode
183
- when :absolute
184
- # Calculate page offset
185
- offset = (Float(position) / size).floor * size
186
-
187
- # Find records
188
- sequence.limit(size, offset)
189
- when :float
190
- count = sequence.count # Total records
191
- if size >= count
192
- # Window includes all records in the sequence
193
- return self.class.find(:all)
194
- else
195
- # Window is smaller than the sequence
196
- position = self.position # This record's position
197
- previous_size = (Float(size - 1) / 2).floor # How many records before
198
- next_size = (Float(size - 1) / 2).ceil # How many records after
163
+ alias :position :previous_count
164
+
165
+ # Returns a collection of records around this record.
166
+ # Mode is one of:
167
+ # 1. :absolute Returns a window containing this record in even multiples from
168
+ # the first record, like a page of a book.
169
+ # 2. :float Returns a centered window of the provided size. If the edge of
170
+ # the sequence is reached, the window shifts to include more
171
+ # elements of the sequence. If no more elements are available
172
+ # (the window is larger than the size of the sequence), the
173
+ # entire sequence is returned. If the size is even, one more
174
+ # record is returned suceeding this record than preceding this
175
+ # record, if possible.
176
+ # 3. :clip Returns a centered window of or smaller than the given size. If
177
+ # the edge of the sequence is reached, the window is clipped.
178
+ def window(mode = :absolute, size = self.class.window_size)
179
+ case mode
180
+ when :absolute
181
+ # Calculate page offset
182
+ offset = (Float(position) / size).floor * size
199
183
 
200
- # Shift window if necessary
201
- if (displacement = previous_size - position) > 0
202
- # The window extends before the start of the sequence
203
- previous_size -= displacement
204
- elsif (displacement = next_size - self.next_count) > 0
205
- # The window extends beyond the end of the sequence
206
- previous_size += displacement
184
+ # Find records
185
+ sequence.limit(size, offset)
186
+ when :float
187
+ count = sequence.count # Total records
188
+ if size >= count
189
+ # Window includes all records in the sequence
190
+ return self.class.find(:all)
191
+ else
192
+ # Window is smaller than the sequence
193
+ position = self.position # This record's position
194
+ previous_size = (Float(size - 1) / 2).floor # How many records before
195
+ next_size = (Float(size - 1) / 2).ceil # How many records after
196
+
197
+ # Shift window if necessary
198
+ if (displacement = previous_size - position) > 0
199
+ # The window extends before the start of the sequence
200
+ previous_size -= displacement
201
+ elsif (displacement = next_size - self.next_count) > 0
202
+ # The window extends beyond the end of the sequence
203
+ previous_size += displacement
204
+ end
205
+
206
+ # Calculate window offset
207
+ offset = position - previous_size
208
+
209
+ # Find records
210
+ sequence.limit(size, offset)
207
211
  end
212
+ when :clip
213
+ position = self.position # Our position in sequence
214
+ previous_size = (Float(size - 1) / 2).floor # How many records before
208
215
 
209
- # Calculate window offset
210
- offset = position - previous_size
216
+ if (displacement = previous_size - position) > 0
217
+ # The window extends before the beginning of the sequence
218
+ size -= displacement
219
+ offset = 0
220
+ else
221
+ # The window doesn't extend before the beginning of the sequence.
222
+ offset = position - previous_size
223
+ end
211
224
 
212
- # Find records
225
+ # Find records.
213
226
  sequence.limit(size, offset)
214
- end
215
- when :clip
216
- position = self.position # Our position in sequence
217
- previous_size = (Float(size - 1) / 2).floor # How many records before
218
-
219
- if (displacement = previous_size - position) > 0
220
- # The window extends before the beginning of the sequence
221
- size -= displacement
222
- offset = 0
223
227
  else
224
- # The window doesn't extend before the beginning of the sequence.
225
- offset = position - previous_size
226
- end
227
-
228
- # Find records.
229
- sequence.limit(size, offset)
230
- else
231
- raise ArgumentError.new('first argument must be one of :absolute, :float, :clip')
228
+ raise ArgumentError.new('first argument must be one of :absolute, :float, :clip')
229
+ end
232
230
  end
233
- end
234
231
 
235
- # Returns a url for this record, viewed in an absolute window. TODO: handle non-default window sizes.
236
- def absolute_window_url(size = self.class.window_size)
237
- page = (Float(position) / size).floor
238
- self.class.url + '/page/' + page.to_s + '#' + self.class.to_s.demodulize.underscore +
239
- '_' + send(self.class.canonical_name_attr)
240
- end
232
+ # Returns a url for this record, viewed in an absolute window. TODO:
233
+ # handle non-default window sizes.
234
+ def absolute_window_url(size = self.class.window_size)
235
+ page = (Float(position) / size).floor
236
+ self.class.url + '/page/' + page.to_s + '#' + self.class.to_s.demodulize.underscore +
237
+ '_' + send(self.class.canonical_name_attr)
238
+ end
241
239
 
242
- # Returns the absolute window index that this record appears in
243
- def absolute_window_index(size = self.class.window_size)
244
- (Float(self.position) / size).floor
240
+ # Returns the absolute window index that this record appears in
241
+ def absolute_window_index(size = self.class.window_size)
242
+ (Float(self.position) / size).floor
243
+ end
245
244
  end
246
245
  end
247
246
  end