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,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 %>