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.
- data/bin/cortex_reaver +7 -2
- data/lib/cortex_reaver.rb +51 -71
- data/lib/cortex_reaver/config.rb +23 -7
- data/lib/cortex_reaver/controller/admin.rb +6 -8
- data/lib/cortex_reaver/controller/comment.rb +17 -17
- data/lib/cortex_reaver/controller/config.rb +3 -2
- data/lib/cortex_reaver/controller/controller.rb +22 -0
- data/lib/cortex_reaver/controller/documentation.rb +1 -3
- data/lib/cortex_reaver/controller/journal.rb +13 -12
- data/lib/cortex_reaver/controller/main.rb +36 -29
- data/lib/cortex_reaver/controller/page.rb +15 -11
- data/lib/cortex_reaver/controller/photograph.rb +21 -15
- data/lib/cortex_reaver/controller/project.rb +16 -13
- data/lib/cortex_reaver/controller/tag.rb +16 -14
- data/lib/cortex_reaver/controller/user.rb +11 -13
- data/lib/cortex_reaver/helper/attachments.rb +18 -12
- data/lib/cortex_reaver/helper/auth.rb +2 -2
- data/lib/cortex_reaver/helper/canonical.rb +2 -2
- data/lib/cortex_reaver/helper/crud.rb +78 -38
- data/lib/cortex_reaver/helper/feeds.rb +2 -5
- data/lib/cortex_reaver/helper/form.rb +1 -1
- data/lib/cortex_reaver/helper/navigation.rb +1 -1
- data/lib/cortex_reaver/helper/photographs.rb +12 -3
- data/lib/cortex_reaver/helper/template.rb +37 -0
- data/lib/cortex_reaver/{view/blank_layout.rhtml → layout/blank.rhtml} +1 -1
- data/lib/cortex_reaver/{view/text_layout.rhtml → layout/text.rhtml} +1 -1
- data/lib/cortex_reaver/migrations/013_draft.rb +17 -0
- data/lib/cortex_reaver/model/comment.rb +64 -53
- data/lib/cortex_reaver/model/journal.rb +23 -21
- data/lib/cortex_reaver/model/model.rb +9 -0
- data/lib/cortex_reaver/model/page.rb +24 -42
- data/lib/cortex_reaver/model/photograph.rb +17 -17
- data/lib/cortex_reaver/model/project.rb +21 -18
- data/lib/cortex_reaver/model/tag.rb +12 -8
- data/lib/cortex_reaver/model/user.rb +79 -41
- data/lib/cortex_reaver/public/css/main.css +4 -0
- data/lib/cortex_reaver/snippets/numeric.rb +15 -0
- data/lib/cortex_reaver/snippets/ramaze/cache/memcached.rb +14 -0
- data/lib/cortex_reaver/support/attachments.rb +113 -105
- data/lib/cortex_reaver/support/cached_rendering.rb +65 -62
- data/lib/cortex_reaver/support/canonical.rb +82 -85
- data/lib/cortex_reaver/support/comments.rb +57 -51
- data/lib/cortex_reaver/support/cortex_reaver_validation_helpers.rb +13 -0
- data/lib/cortex_reaver/support/sequenceable.rb +202 -203
- data/lib/cortex_reaver/support/tags.rb +103 -94
- data/lib/cortex_reaver/support/timestamps.rb +27 -21
- data/lib/cortex_reaver/support/viewable.rb +17 -0
- data/lib/cortex_reaver/version.rb +3 -3
- data/lib/cortex_reaver/view/admin/index.rhtml +2 -2
- data/lib/cortex_reaver/view/comments/comment.rhtml +4 -1
- data/lib/cortex_reaver/view/comments/list.rhtml +1 -1
- data/lib/cortex_reaver/view/comments/post_form.rhtml +1 -1
- data/lib/cortex_reaver/view/journals/form.rhtml +3 -1
- data/lib/cortex_reaver/view/journals/journal.rhtml +6 -4
- data/lib/cortex_reaver/view/journals/list.rhtml +2 -2
- data/lib/cortex_reaver/view/journals/show.rhtml +1 -1
- data/lib/cortex_reaver/view/pages/form.rhtml +2 -1
- data/lib/cortex_reaver/view/pages/list.rhtml +2 -2
- data/lib/cortex_reaver/view/pages/show.rhtml +1 -1
- data/lib/cortex_reaver/view/photographs/form.rhtml +7 -3
- data/lib/cortex_reaver/view/photographs/list.rhtml +1 -1
- data/lib/cortex_reaver/view/photographs/show.rhtml +7 -7
- data/lib/cortex_reaver/view/projects/form.rhtml +1 -0
- data/lib/cortex_reaver/view/projects/list.rhtml +3 -3
- data/lib/cortex_reaver/view/projects/show.rhtml +5 -2
- data/lib/cortex_reaver/view/tags/list.rhtml +6 -2
- data/lib/cortex_reaver/view/tags/show.rhtml +10 -5
- data/lib/cortex_reaver/view/users/form.rhtml +1 -1
- data/lib/cortex_reaver/view/users/list.rhtml +5 -2
- data/lib/cortex_reaver/view/users/login.rhtml +1 -1
- data/lib/cortex_reaver/view/users/show.rhtml +5 -1
- metadata +159 -149
- data/lib/cortex_reaver/public/dispatch.fcgi +0 -11
- data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +0 -37
- data/lib/cortex_reaver/support/pagination.rb +0 -38
- data/lib/cortex_reaver/view/error.rhtml +0 -72
- data/lib/cortex_reaver/view/photographs/short.rhtml +0 -3
@@ -1,119 +1,128 @@
|
|
1
|
-
module
|
2
|
-
module
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
3
|
module Tags
|
4
4
|
# Support for taggable models
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
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
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
107
|
+
# Get rid of empty tags
|
108
|
+
tags.reject do |tag|
|
109
|
+
tag.nil?
|
110
|
+
end
|
111
|
+
tags.uniq!
|
103
112
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
2
|
-
module
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
3
|
# Supports updated_on and created_on behavior
|
4
4
|
module Timestamps
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
29
|
+
def skip_timestamp_update=(boolean)
|
30
|
+
@skip_timestamp_update = boolean
|
31
|
+
end
|
27
32
|
|
28
|
-
|
29
|
-
|
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
|
4
|
-
APP_AUTHOR = '
|
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
|
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><%=
|
5
|
-
<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
|
-
|
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
|
-
<%=
|
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="<%=
|
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="<%=
|
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
|
-
|
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
|
-
<%=
|
36
|
+
<%= CortexReaver::CommentController.render_view :comment, 'comment' => comment %>
|
35
37
|
<% end %>
|
36
38
|
</div>
|
37
39
|
|
38
|
-
<%=
|
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
|
-
<%=
|
23
|
+
<%= CortexReaver::JournalController.render_view :journal, 'journal' => journal, 'hide_comments' => true %>
|
24
24
|
<% end %>
|
25
25
|
|
26
|
-
<% if @page.nil? and @journals.
|
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>
|
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
<%= errors_on @page %>
|
4
4
|
|
5
|
-
<form class="edit-form" action="<%=
|
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><%=
|
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><%=
|
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 %>
|