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,119 +1,128 @@
1
- module CortexReaver
2
- module Model
1
+ module Sequel
2
+ module Plugins
3
3
  module Tags
4
4
  # Support for taggable models
5
-
6
- def self.included(base)
7
- base.class_eval do
8
- # If tags have changed, make sure to update those tags' counts.
9
- after_save(:update_tag_counts) do
10
- if @added_tags
11
- @added_tags.each do |tag|
12
- tag.count += 1
13
- tag.save
14
- end
15
- @removed_tags.each do |tag|
16
- tag.count -= 1
17
- tag.save
18
- end
19
- end
5
+ module ClassMethods
6
+ # Returns all models with ANY of the following tags
7
+ def tagged_with_any_of(tags)
8
+ tagged_with(tags, false)
9
+ end
10
+
11
+ # Returns all models with ALL the following tags:
12
+ def tagged_with(tags, all=true)
13
+ # Find map between this model and tags, e.g. pages_tags
14
+ map = [table_name.to_s, 'tags'].sort.join('_').to_sym
15
+
16
+ # The name in the mapping table which points to us
17
+ own_id = (table_name.to_s.singularize + '_id').to_sym
18
+
19
+ # The tag IDs to search for
20
+ ids = tags.map { |t| t.id }
21
+
22
+ # Now filter this model, finding all ids which appear n times with
23
+ # the same model_id in the mapping table, which has been filtered
24
+ # to contain only rows with one of our interesting tags.
25
+ #
26
+ # Man, don't you wish MySQL had intersect?
27
+ if all
28
+ filter(:id =>
29
+ CortexReaver.db[map].filter(:tag_id => ids).group(own_id).having(
30
+ "count(*) = #{ids.size}"
31
+ ).select(own_id)
32
+ )
33
+ else
34
+ filter(:id =>
35
+ CortexReaver.db[map].filter(:tag_id => ids).select(own_id)
36
+ )
20
37
  end
38
+ end
39
+ end
40
+
41
+ module InstanceMethods
42
+ # If tags have changed, make sure to update those tags' counts.
43
+ def after_save
44
+ return false if super == false
21
45
 
22
- # Remove tags on deletion
23
- before_destroy(:drop_associated_tags) do
24
- tags.each do |tag|
46
+ if @added_tags
47
+ @added_tags.each do |tag|
48
+ tag.count += 1
49
+ tag.save
50
+ end
51
+ @removed_tags.each do |tag|
25
52
  tag.count -= 1
26
- if tag.count == 0
27
- tag.destroy
28
- else
29
- tag.save
30
- end
53
+ tag.save
31
54
  end
32
- remove_all_tags
33
55
  end
34
56
 
35
- # Returns all models with ANY of the following tags
36
- def self.tagged_with_any_of(tags)
37
- tagged_with(tags, false)
38
- end
39
-
40
- # Returns all models with ALL the following tags:
41
- def self.tagged_with(tags, all=true)
42
- # Find map between this model and tags, e.g. pages_tags
43
- map = [table_name.to_s, 'tags'].sort.join('_').to_sym
44
-
45
- # The name in the mapping table which points to us
46
- own_id = (table_name.to_s.singularize + '_id').to_sym
47
-
48
- # The tag IDs to search for
49
- ids = tags.map { |t| t.id }
50
-
51
- # Now filter this model, finding all ids which appear n times with
52
- # the same model_id in the mapping table, which has been filtered
53
- # to contain only rows with one of our interesting tags.
54
- #
55
- # Man, don't you wish MySQL had intersect?
56
- if all
57
- filter(:id =>
58
- CortexReaver.db[map].filter(:tag_id => ids).group(own_id).having(
59
- "count(*) = #{ids.size}"
60
- ).select(own_id)
61
- )
57
+ true
58
+ end
59
+
60
+ # Remove tags on deletion
61
+ def before_destroy
62
+ Ramaze::Log.debug 'remove tags'
63
+ return false unless super
64
+ Ramaze::Log.debug 'removing tags'
65
+
66
+ tags.each do |tag|
67
+ tag.count -= 1
68
+ if tag.count == 0
69
+ tag.destroy
62
70
  else
63
- filter(:id =>
64
- CortexReaver.db[map].filter(:tag_id => ids).select(own_id)
65
- )
71
+ tag.save
66
72
  end
67
73
  end
74
+ remove_all_tags
75
+
76
+
77
+ true
68
78
  end
69
- end
70
79
 
71
- # Set tags from a string, or array of tags. Finds existing tags or
72
- # creates new ones. Also updates tag counts.
73
- def tags=(tags)
74
- if tags.kind_of? String
75
- tags = tags.squeeze(',').split(',').map do |title|
76
- title.strip!
77
- if title.blank?
78
- # Do nothing
79
- tag = nil
80
- else
81
- # Look up existing tag
82
- tag = Tag[:title => title]
83
- # Or create new one
84
- tag ||= Tag.create(:title => title, :name => Tag.canonicalize(title))
85
- unless tag
86
- # Everything failed
87
- raise RuntimeError.new("couldn't find or create tag for #{title}")
80
+ # Set tags from a string, or array of tags. Finds existing tags or
81
+ # creates new ones. Also updates tag counts.
82
+ def tags=(tags)
83
+ if tags.kind_of? String
84
+ tags = tags.squeeze(',').split(',').map do |title|
85
+ title.strip!
86
+ if title.blank?
87
+ # Do nothing
88
+ tag = nil
89
+ else
90
+ # Look up existing tag
91
+ tag = CortexReaver::Tag[:title => title]
92
+ # Or create new one
93
+ tag ||= CortexReaver::Tag.create(:title => title, :name => CortexReaver::Tag.canonicalize(title))
94
+ unless tag
95
+ # Everything failed
96
+ raise RuntimeError.new("couldn't find or create tag for #{title}")
97
+ end
88
98
  end
99
+ tag
89
100
  end
90
- tag
91
101
  end
92
- end
93
102
 
94
- unless tags.respond_to? :each
95
- raise ArgumentError.new("Needed a string or Enumerable of Tags, got #{tags.class}")
96
- end
103
+ unless tags.respond_to? :each
104
+ raise ArgumentError.new("Needed a string or Enumerable of Tags, got #{tags.class}")
105
+ end
97
106
 
98
- # Get rid of empty tags
99
- tags.reject do |tag|
100
- tag.nil?
101
- end
102
- tags.uniq!
107
+ # Get rid of empty tags
108
+ tags.reject do |tag|
109
+ tag.nil?
110
+ end
111
+ tags.uniq!
103
112
 
104
- # Find which tags to change. Their counts are updated by an after_save
105
- # callback.
106
- old_tags = self.tags
107
- @removed_tags = old_tags - tags
108
- @added_tags = tags - old_tags
113
+ # Find which tags to change. Their counts are updated by an after_save
114
+ # callback.
115
+ old_tags = self.tags
116
+ @removed_tags = old_tags - tags
117
+ @added_tags = tags - old_tags
109
118
 
110
- # Change own tags
111
- remove_all_tags
112
- tags.each do |tag|
113
- add_tag tag
119
+ # Change own tags
120
+ remove_all_tags
121
+ tags.each do |tag|
122
+ add_tag tag
123
+ end
114
124
  end
115
125
  end
116
-
117
126
  end
118
127
  end
119
128
  end
@@ -1,32 +1,38 @@
1
- module CortexReaver
2
- module Model
1
+ module Sequel
2
+ module Plugins
3
3
  # Supports updated_on and created_on behavior
4
4
  module Timestamps
5
- def self.included(base)
6
- base.class_eval do
7
- # Create
8
- before_create(:init_timestamp) do
9
- unless skip_timestamp_update?
10
- self.created_on = Time.now
11
- self.updated_on = Time.now
12
- end
5
+ module InstanceMethods
6
+ # Create
7
+ def before_create
8
+ return false if super == false
9
+
10
+ unless skip_timestamp_update?
11
+ self.created_on = Time.now
12
+ self.updated_on = Time.now
13
13
  end
14
14
 
15
- # Update
16
- before_update(:update_timestamp) do
17
- unless skip_timestamp_update?
18
- self.updated_on = Time.now
19
- end
15
+ true
16
+ end
17
+
18
+ # Update
19
+ def before_update
20
+ return false if super == false
21
+
22
+ unless skip_timestamp_update?
23
+ self.updated_on = Time.now
20
24
  end
25
+
26
+ true
21
27
  end
22
- end
23
28
 
24
- def skip_timestamp_update=(boolean)
25
- @skip_timestamp_update = boolean
26
- end
29
+ def skip_timestamp_update=(boolean)
30
+ @skip_timestamp_update = boolean
31
+ end
27
32
 
28
- def skip_timestamp_update?
29
- @skip_timestamp_update
33
+ def skip_timestamp_update?
34
+ @skip_timestamp_update
35
+ end
30
36
  end
31
37
  end
32
38
  end
@@ -0,0 +1,17 @@
1
+ module Sequel
2
+ module Plugins
3
+ module Viewable
4
+ module DatasetMethods
5
+ def viewable_by(user)
6
+ if user.anonymous?
7
+ self.exclude(:draft => true)
8
+ elsif user.admin? or user.editor?
9
+ self
10
+ else
11
+ self.exclude(:draft => true).or(:created_by => user.id)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,8 +1,8 @@
1
1
  module CortexReaver
2
2
  APP_NAME = 'Cortex Reaver'
3
- APP_VERSION = '0.0.9'
4
- APP_AUTHOR = 'aphyr'
3
+ APP_VERSION = '0.1.0'
4
+ APP_AUTHOR = 'Kyle Kingsbury'
5
5
  APP_EMAIL = 'aphyr@aphyr.com'
6
6
  APP_URL = 'http://aphyr.com'
7
- APP_COPYRIGHT = 'Copyright (c) 2009 aphyr <aphyr@aphyr.com>. All rights reserved.'
7
+ APP_COPYRIGHT = 'Copyright (c) 2009 Kyle Kingsbury <aphyr@aphyr.com>. All rights reserved.'
8
8
  end
@@ -1,6 +1,6 @@
1
1
  <h2>Administration</h2>
2
2
 
3
3
  <ul>
4
- <li><%= A('Update comment counts', :href => Rs(:update_comments)) %></li>
5
- <li><%= A('Update tags', :href => Rs(:update_tags)) %></li>
4
+ <li><%= a('Update comment counts', rs(:update_comments)) %></li>
5
+ <li><%= a('Update tags', rs(:update_tags)) %></li>
6
6
  </ul>
@@ -19,7 +19,10 @@
19
19
  <% end %>
20
20
  <% if user.can_delete? @comment %>
21
21
  <li>
22
- <%= A '<img src="/images/delete.gif" class="icon" alt="delete" /> Delete', :href => "/comments/delete/#{@comment.id}", :onclick => "return confirm('Are you sure you wish to delete this comment?');" %></li>
22
+ <a href="<%= CortexReaver::CommentController.r(:delete, @comment.id) %>" onclick="return confirm('Are you sure you want to delete this comment?');">
23
+ <img src="/images/delete.gif" class="icon" alt="delete" /> Delete
24
+ </a>
25
+ </li>
23
26
  <% end %>
24
27
  </ul>
25
28
  </div>
@@ -1,5 +1,5 @@
1
1
  <div class="comments">
2
2
  <% @comments.all.each do |comment| %>
3
- <%= render_template 'comment.rhtml', 'comment' => comment, 'hide_comments' => true %>
3
+ <%= CortexReaver::CommentController.render_view 'comment', 'comment' => comment, 'hide_comments' => true %>
4
4
  <% end %>
5
5
  </div>
@@ -11,7 +11,7 @@
11
11
  </div>
12
12
  <% end %>
13
13
 
14
- <form class="comment-form" action="<%= R(CortexReaver::CommentController, :post) %>" method="post">
14
+ <form class="comment-form" action="<%= CortexReaver::CommentController.r :post %>" method="post">
15
15
  <%= form_p :title, :model => @new_comment %>
16
16
  <p class="dont-read-me">
17
17
  Please avoid writing anything here unless you are a computer:
@@ -2,12 +2,14 @@
2
2
 
3
3
  <%= errors_on @journal %>
4
4
 
5
- <form class="edit-form" action="<%= Rs(@form_action) %>" method="post" enctype="multipart/form-data">
5
+ <form class="edit-form" action="<%= rs(@form_action) %>" method="post" enctype="multipart/form-data">
6
6
  <%= form_p :title, :model => @journal %>
7
7
  <%= live_name_field @journal %>
8
8
  <%= live_tags_field @journal %>
9
9
 
10
10
  <%= form_p :body, :model => @journal, :type => 'textarea', :description => 'Body (<a href="/documentation/formatting" />Formatting Help</a>)' %>
11
+
11
12
  <%= attachment_form @journal %>
13
+ <%= form_p :draft, :model => @journal, :type => 'checkbox', :description => 'This is a draft' %>
12
14
  <input type="submit" name="submit" />
13
15
  </form>
@@ -1,4 +1,4 @@
1
- <div class="journal text-entry <%= @journal.tags.map {|t| 'tagged_' + t.name}.join(' ')%>">
1
+ <div class="journal text-entry <%= @journal.tags.map {|t| 'tagged_' + t.name}.join(' ')%> <%= @journal.draft ? 'draft' : ''%>">
2
2
  <h2><a id="journal_<%= @journal.name %>" href="<%= @journal.url %>"><%=h @journal.title %></a></h2>
3
3
  <div class="byline">
4
4
  <%= author_info @journal %>
@@ -21,7 +21,9 @@
21
21
  <% end %>
22
22
  <% if user.can_delete? @journal %>
23
23
  <li>
24
- <%= A '<img src="/images/delete.gif" class="icon" alt="delete" /> Delete', :href => "/journals/delete/#{@journal.id}", :onclick => "return confirm('Are you sure you want to delete this journal?');" %>
24
+ <a href="<%= CortexReaver::JournalController.r(:delete, @journal.id) %>" onclick="return confirm('Are you sure you want to delete this journal?');">
25
+ <img src="/images/delete.gif" class="icon" alt="delete" /> Delete
26
+ </a>
25
27
  </li>
26
28
  <% end %>
27
29
  </ul>
@@ -31,10 +33,10 @@
31
33
  <div class="comments">
32
34
  <a id="comments" />
33
35
  <% @journal.comments_dataset.order(:created_on).all.each do |comment| %>
34
- <%= render_template '../comments/comment.rhtml', 'comment' => comment %>
36
+ <%= CortexReaver::CommentController.render_view :comment, 'comment' => comment %>
35
37
  <% end %>
36
38
  </div>
37
39
 
38
- <%= render_template '../comments/post_form.rhtml', 'comment' => @new_comment %>
40
+ <%= CortexReaver::CommentController.render_view :post_form, 'comment' => @new_comment %>
39
41
  <% end %>
40
42
  </div>
@@ -20,10 +20,10 @@
20
20
 
21
21
  <div class="journals">
22
22
  <% @journals.all.each do |journal| %>
23
- <%= render_template Ramaze::Global.view_root + '/journals/journal.rhtml', 'journal' => journal, 'hide_comments' => true %>
23
+ <%= CortexReaver::JournalController.render_view :journal, 'journal' => journal, 'hide_comments' => true %>
24
24
  <% end %>
25
25
 
26
- <% if @page.nil? and @journals.size > 0 and @journals.all.last.previous %>
26
+ <% if @page.nil? and @journals.count > 0 and @journals.all.last.previous %>
27
27
  <p><a href="<%= @journals.all.last.previous.absolute_window_url %>">Continue reading on journal page <%= @journals.all.last.previous.absolute_window_index %></a></p>
28
28
  <% end %>
29
29
  </div>
@@ -1,5 +1,5 @@
1
1
  <%= model_nav @journal %>
2
2
 
3
- <%= render_template 'journal.rhtml', 'journal' => @journal %>
3
+ <%= CortexReaver::JournalController.render_view :journal, 'journal' => @journal %>
4
4
 
5
5
  <%= model_nav @journal %>
@@ -2,12 +2,13 @@
2
2
 
3
3
  <%= errors_on @page %>
4
4
 
5
- <form class="edit-form" action="<%= Rs(@form_action) %>" method="post" enctype="multipart/form-data">
5
+ <form class="edit-form" action="<%= rs(@form_action) %>" method="post" enctype="multipart/form-data">
6
6
  <%= page_select 'page_id', :default_id => @page.page_id, :skip_id => @page.id, :description => 'Parent page' %>
7
7
  <%= form_p 'title', :model => @page %>
8
8
  <%= live_name_field @page %>
9
9
  <%= live_tags_field @page %>
10
10
  <%= form_p :body, :model => @page, :type => 'textarea' %>
11
11
  <%= attachment_form @page %>
12
+ <%= form_p :draft, :model => @page, :type => 'checkbox', :description => 'This is a draft' %>
12
13
  <input type="submit" name="submit" />
13
14
  </form>
@@ -15,13 +15,13 @@
15
15
  <tbody>
16
16
  <% @pages.all.each do |page| %>
17
17
  <tr>
18
- <td><%= A(page.name, :href => page.url) %></td>
18
+ <td><%= a(page.name, page.url) %></td>
19
19
  <td><%= page.title %></td>
20
20
  <% if user.can_edit? page %>
21
21
  <td><a href="/pages/edit/<%= page.id %>">Edit</a></td>
22
22
  <% end %>
23
23
  <% if user.can_delete? page %>
24
- <td><%= A 'Delete', :href => "/pages/delete/#{page.id}", :onclick => "return confirm('Are you sure you want to delete this page?');" %></td>
24
+ <td><%= a 'Delete', CortexReaver::PageController.r(:delete, :id => page.id), :onclick => "return confirm('Are you sure you want to delete this page?');" %></td>
25
25
  <% end %>
26
26
  </tr>
27
27
  <% end %>