cortex-reaver 0.0.1

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 (128) hide show
  1. data/LICENSE +25 -0
  2. data/README +48 -0
  3. data/bin/console +11 -0
  4. data/bin/cortex_reaver +110 -0
  5. data/bin/import.rb +78 -0
  6. data/lib/cortex_reaver.rb +114 -0
  7. data/lib/cortex_reaver/config.rb +21 -0
  8. data/lib/cortex_reaver/controller/comment.rb +113 -0
  9. data/lib/cortex_reaver/controller/config.rb +14 -0
  10. data/lib/cortex_reaver/controller/journal.rb +40 -0
  11. data/lib/cortex_reaver/controller/main.rb +56 -0
  12. data/lib/cortex_reaver/controller/page.rb +34 -0
  13. data/lib/cortex_reaver/controller/photograph.rb +45 -0
  14. data/lib/cortex_reaver/controller/project.rb +40 -0
  15. data/lib/cortex_reaver/controller/tag.rb +67 -0
  16. data/lib/cortex_reaver/controller/user.rb +71 -0
  17. data/lib/cortex_reaver/helper/activity.rb +9 -0
  18. data/lib/cortex_reaver/helper/attachments.rb +139 -0
  19. data/lib/cortex_reaver/helper/auth.rb +45 -0
  20. data/lib/cortex_reaver/helper/canonical.rb +55 -0
  21. data/lib/cortex_reaver/helper/crud.rb +317 -0
  22. data/lib/cortex_reaver/helper/date.rb +29 -0
  23. data/lib/cortex_reaver/helper/error.rb +14 -0
  24. data/lib/cortex_reaver/helper/feeds.rb +88 -0
  25. data/lib/cortex_reaver/helper/form.rb +114 -0
  26. data/lib/cortex_reaver/helper/navigation.rb +142 -0
  27. data/lib/cortex_reaver/helper/photographs.rb +25 -0
  28. data/lib/cortex_reaver/helper/tags.rb +47 -0
  29. data/lib/cortex_reaver/helper/workflow.rb +27 -0
  30. data/lib/cortex_reaver/migrations/001_users.rb +24 -0
  31. data/lib/cortex_reaver/migrations/002_pages.rb +29 -0
  32. data/lib/cortex_reaver/migrations/003_journals.rb +26 -0
  33. data/lib/cortex_reaver/migrations/004_photographs.rb +24 -0
  34. data/lib/cortex_reaver/migrations/005_projects.rb +27 -0
  35. data/lib/cortex_reaver/migrations/006_tags.rb +64 -0
  36. data/lib/cortex_reaver/migrations/007_comments.rb +40 -0
  37. data/lib/cortex_reaver/migrations/008_config.rb +23 -0
  38. data/lib/cortex_reaver/model/comment.rb +109 -0
  39. data/lib/cortex_reaver/model/journal.rb +53 -0
  40. data/lib/cortex_reaver/model/page.rb +87 -0
  41. data/lib/cortex_reaver/model/photograph.rb +133 -0
  42. data/lib/cortex_reaver/model/project.rb +49 -0
  43. data/lib/cortex_reaver/model/tag.rb +72 -0
  44. data/lib/cortex_reaver/model/user.rb +147 -0
  45. data/lib/cortex_reaver/public/css/admin.css +45 -0
  46. data/lib/cortex_reaver/public/css/custom.css +0 -0
  47. data/lib/cortex_reaver/public/css/form.css +51 -0
  48. data/lib/cortex_reaver/public/css/main.css +325 -0
  49. data/lib/cortex_reaver/public/css/photo.css +113 -0
  50. data/lib/cortex_reaver/public/css/ramaze_error.css +90 -0
  51. data/lib/cortex_reaver/public/css/text.css +25 -0
  52. data/lib/cortex_reaver/public/dispatch.fcgi +11 -0
  53. data/lib/cortex_reaver/public/images/CortexReaver.gif +0 -0
  54. data/lib/cortex_reaver/public/images/atom-xml-icon.png +0 -0
  55. data/lib/cortex_reaver/public/images/body.png +0 -0
  56. data/lib/cortex_reaver/public/images/border_bottom.png +0 -0
  57. data/lib/cortex_reaver/public/images/border_bottom_left.png +0 -0
  58. data/lib/cortex_reaver/public/images/border_bottom_right.png +0 -0
  59. data/lib/cortex_reaver/public/images/border_left.png +0 -0
  60. data/lib/cortex_reaver/public/images/border_right.png +0 -0
  61. data/lib/cortex_reaver/public/images/border_top.png +0 -0
  62. data/lib/cortex_reaver/public/images/border_top_left.png +0 -0
  63. data/lib/cortex_reaver/public/images/border_top_right.png +0 -0
  64. data/lib/cortex_reaver/public/images/comment.gif +0 -0
  65. data/lib/cortex_reaver/public/images/dark_trans.png +0 -0
  66. data/lib/cortex_reaver/public/images/delete.gif +0 -0
  67. data/lib/cortex_reaver/public/images/edit.gif +0 -0
  68. data/lib/cortex_reaver/public/images/header.png +0 -0
  69. data/lib/cortex_reaver/public/images/header.xcf +0 -0
  70. data/lib/cortex_reaver/public/images/header_background.png +0 -0
  71. data/lib/cortex_reaver/public/images/parent.gif +0 -0
  72. data/lib/cortex_reaver/public/images/rss-xml-icon.png +0 -0
  73. data/lib/cortex_reaver/public/images/sections.png +0 -0
  74. data/lib/cortex_reaver/public/images/sections_highlight.png +0 -0
  75. data/lib/cortex_reaver/public/js/admin.js +36 -0
  76. data/lib/cortex_reaver/public/js/cookie.js +27 -0
  77. data/lib/cortex_reaver/public/js/jquery.js +32 -0
  78. data/lib/cortex_reaver/public/js/photo.js +33 -0
  79. data/lib/cortex_reaver/snippets/array.rb +7 -0
  80. data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +37 -0
  81. data/lib/cortex_reaver/support/attachments.rb +235 -0
  82. data/lib/cortex_reaver/support/cached_rendering.rb +79 -0
  83. data/lib/cortex_reaver/support/canonical.rb +107 -0
  84. data/lib/cortex_reaver/support/comments.rb +69 -0
  85. data/lib/cortex_reaver/support/pagination.rb +38 -0
  86. data/lib/cortex_reaver/support/renderer.rb +196 -0
  87. data/lib/cortex_reaver/support/sequenceable.rb +248 -0
  88. data/lib/cortex_reaver/support/tags.rb +108 -0
  89. data/lib/cortex_reaver/support/timestamps.rb +33 -0
  90. data/lib/cortex_reaver/version.rb +8 -0
  91. data/lib/cortex_reaver/view/adminbox.rhtml +56 -0
  92. data/lib/cortex_reaver/view/blank_layout.rhtml +46 -0
  93. data/lib/cortex_reaver/view/comments/comment.rhtml +34 -0
  94. data/lib/cortex_reaver/view/comments/form.rhtml +25 -0
  95. data/lib/cortex_reaver/view/comments/list.rhtml +5 -0
  96. data/lib/cortex_reaver/view/comments/post_form.rhtml +36 -0
  97. data/lib/cortex_reaver/view/config/form.rhtml +10 -0
  98. data/lib/cortex_reaver/view/error.rhtml +72 -0
  99. data/lib/cortex_reaver/view/journals/form.rhtml +12 -0
  100. data/lib/cortex_reaver/view/journals/journal.rhtml +39 -0
  101. data/lib/cortex_reaver/view/journals/list.rhtml +33 -0
  102. data/lib/cortex_reaver/view/journals/short.rhtml +3 -0
  103. data/lib/cortex_reaver/view/journals/show.rhtml +5 -0
  104. data/lib/cortex_reaver/view/pages/form.rhtml +12 -0
  105. data/lib/cortex_reaver/view/pages/list.rhtml +26 -0
  106. data/lib/cortex_reaver/view/pages/show.rhtml +12 -0
  107. data/lib/cortex_reaver/view/photographs/atom_fragment.rhtml +82 -0
  108. data/lib/cortex_reaver/view/photographs/form.rhtml +19 -0
  109. data/lib/cortex_reaver/view/photographs/grid.rhtml +36 -0
  110. data/lib/cortex_reaver/view/photographs/list.rhtml +9 -0
  111. data/lib/cortex_reaver/view/photographs/short.rhtml +3 -0
  112. data/lib/cortex_reaver/view/photographs/show.rhtml +114 -0
  113. data/lib/cortex_reaver/view/photographs/sidebar.rhtml +7 -0
  114. data/lib/cortex_reaver/view/projects/form.rhtml +13 -0
  115. data/lib/cortex_reaver/view/projects/list.rhtml +27 -0
  116. data/lib/cortex_reaver/view/projects/show.rhtml +38 -0
  117. data/lib/cortex_reaver/view/tags/form.rhtml +9 -0
  118. data/lib/cortex_reaver/view/tags/list.rhtml +28 -0
  119. data/lib/cortex_reaver/view/tags/show.rhtml +51 -0
  120. data/lib/cortex_reaver/view/text_layout.rhtml +78 -0
  121. data/lib/cortex_reaver/view/users/form.rhtml +16 -0
  122. data/lib/cortex_reaver/view/users/list.rhtml +38 -0
  123. data/lib/cortex_reaver/view/users/login.rhtml +13 -0
  124. data/lib/cortex_reaver/view/users/register.rhtml +13 -0
  125. data/lib/cortex_reaver/view/users/show.rhtml +37 -0
  126. data/lib/cortex_reaver/view/users/user.rhtml +35 -0
  127. data/lib/proto/cortex_reaver.yaml +28 -0
  128. metadata +285 -0
@@ -0,0 +1,24 @@
1
+ module CortexReaver
2
+ class UserSchema < Sequel::Migration
3
+ def down
4
+ drop_table :users if table_exists? :users
5
+ end
6
+
7
+ def up
8
+ unless table_exists? :users
9
+ create_table :users do
10
+ primary_key :id
11
+ varchar :login, :index => true, :unique => true, :null => false
12
+ varchar :name
13
+ varchar :http
14
+ varchar :email
15
+ varchar :password
16
+ varchar :salt
17
+ boolean :admin, :default => false
18
+ datetime :created_on, :null => false
19
+ datetime :updated_on, :null => false
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module CortexReaver
2
+ class PageSchema < Sequel::Migration
3
+ def down
4
+ drop_table :pages if table_exists? :pages
5
+ end
6
+
7
+ def up
8
+ unless table_exists? :pages
9
+ create_table :pages do
10
+ primary_key :id
11
+
12
+ foreign_key :user_id, :table => :users
13
+ index :user_id
14
+
15
+ varchar :name, :null => false, :unique => true, :index => true
16
+ varchar :title, :null => false
17
+
18
+ text :body, :default => ''
19
+ text :body_cache, :default => ''
20
+
21
+ integer :comment_count, :null => false, :default => 0
22
+
23
+ datetime :created_on, :null => false
24
+ datetime :updated_on, :null => false
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module CortexReaver
2
+ class JournalSchema < Sequel::Migration
3
+ def down
4
+ drop_table :journals if table_exists? :journals
5
+ end
6
+
7
+ def up
8
+ unless table_exists? :journals
9
+ create_table :journals do
10
+ primary_key :id
11
+
12
+ foreign_key :user_id, :table => :users
13
+ index :user_id
14
+
15
+ varchar :name, :null => false, :unique => true, :index => true
16
+ text :title, :null => false
17
+ text :body, :default => ''
18
+ text :body_cache, :default => ''
19
+ integer :comment_count, :null => false, :default => 0
20
+ datetime :created_on, :null => false
21
+ datetime :updated_on, :null => false
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ module CortexReaver
2
+ class PhotographSchema < Sequel::Migration
3
+ def down
4
+ drop_table :photographs if table_exists? :photographs
5
+ end
6
+
7
+ def up
8
+ unless table_exists? :photographs
9
+ create_table :photographs do
10
+ primary_key :id
11
+
12
+ foreign_key :user_id, :table => :users
13
+ index :user_id
14
+
15
+ varchar :name, :null => false, :unique => true, :index => true
16
+ text :title, :null => false
17
+ integer :comment_count, :null => false, :default => 0
18
+ datetime :created_on, :null => false
19
+ datetime :updated_on, :null => false
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ module CortexReaver
2
+ class ProjectSchema < Sequel::Migration
3
+ def down
4
+ drop_table :projects if table_exists? :projects
5
+ end
6
+
7
+ def up
8
+ unless table_exists? :projects
9
+ create_table :projects do
10
+ primary_key :id
11
+
12
+ foreign_key :user_id, :table => :users
13
+ index :user_id
14
+
15
+ varchar :name, :null => false, :unique => true, :index => true
16
+ text :title, :null => false
17
+ text :description, :null => false, :default => ''
18
+ text :body, :default => ''
19
+ text :body_cache, :default => ''
20
+ integer :comment_count, :null => false, :default => 0
21
+ datetime :created_on, :null => false
22
+ datetime :updated_on, :null => false
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,64 @@
1
+ module CortexReaver
2
+ class TagSchema < Sequel::Migration
3
+ def down
4
+ [:journals_tags, :photographs_tags, :projects_tags, :pages_tags, :tags].each do |table|
5
+ drop_table table if table_exists? table
6
+ end
7
+ end
8
+
9
+ def up
10
+ unless table_exists? :tags
11
+ create_table :tags do
12
+ primary_key :id
13
+ varchar :name, :null => false, :index => true, :unique => true
14
+ integer :count, :null => false, :default => 0
15
+ varchar :title, :null => false
16
+ end
17
+ end
18
+
19
+ unless table_exists? :journals_tags
20
+ create_table :journals_tags do
21
+ primary_key :id
22
+
23
+ foreign_key :journal_id, :table => :journals
24
+ foreign_key :tag_id, :table => :tags
25
+
26
+ unique [:journal_id, :tag_id]
27
+ end
28
+ end
29
+
30
+ unless table_exists? :photographs_tags
31
+ create_table :photographs_tags do
32
+ primary_key :id
33
+
34
+ foreign_key :photograph_id, :table => :photographs
35
+ foreign_key :tag_id, :table => :tags
36
+
37
+ unique [:photograph_id, :tag_id]
38
+ end
39
+ end
40
+
41
+ unless table_exists? :projects_tags
42
+ create_table :projects_tags do
43
+ primary_key :id
44
+
45
+ foreign_key :project_id, :table => :projects
46
+ foreign_key :tag_id, :table => :tags
47
+
48
+ unique [:project_id, :tag_id]
49
+ end
50
+ end
51
+
52
+ unless table_exists? :pages_tags
53
+ create_table :pages_tags do
54
+ primary_key :id
55
+
56
+ foreign_key :page_id, :table => :pages
57
+ foreign_key :tag_id, :table => :tags
58
+
59
+ unique [:page_id, :tag_id]
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,40 @@
1
+ module CortexReaver
2
+ class CommentSchema < Sequel::Migration
3
+ def down
4
+ drop_table :comments if table_exists? :comments
5
+ end
6
+
7
+ def up
8
+ unless table_exists? :comments
9
+ create_table :comments do
10
+ primary_key :id
11
+
12
+ foreign_key :user_id, :table => :users
13
+ index :user_id
14
+
15
+ foreign_key :journal_id, :table => :journals
16
+ index :journal_id
17
+ foreign_key :photograph_id, :table => :photographs
18
+ index :photograph_id
19
+ foreign_key :project_id, :table => :projects
20
+ index :project_id
21
+ foreign_key :comment_id, :table => :comments
22
+ index :comment_id
23
+ foreign_key :page_id, :table => :pages
24
+ index :page_id
25
+
26
+ varchar :title
27
+ text :name
28
+ text :http
29
+ text :email
30
+ text :body, :default => ''
31
+ text :body_cache, :default => ''
32
+ integer :comment_count, :null => false, :default => 0
33
+
34
+ datetime :created_on
35
+ datetime :updated_on
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ module CortexReaver
2
+ class ConfigSchema < Sequel::Migration
3
+ def down
4
+ drop_table :config if table_exists? :config
5
+ end
6
+
7
+ def up
8
+ unless table_exists? :config
9
+ create_table :config do
10
+ primary_key :id
11
+ varchar :name
12
+ varchar :author
13
+ varchar :description
14
+ boolean :debug, :default => false
15
+ varchar :url
16
+ text :keywords
17
+ datetime :created_on, :null => false
18
+ datetime :updated_on, :null => false
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,109 @@
1
+ module CortexReaver
2
+ class Comment < Sequel::Model(:comments)
3
+ include CortexReaver::Model::Timestamps
4
+ include CortexReaver::Model::CachedRendering
5
+ include CortexReaver::Model::Renderer
6
+ include CortexReaver::Model::Comments
7
+ include CortexReaver::Model::Sequenceable
8
+
9
+ belongs_to :user, :class => 'CortexReaver::User'
10
+ belongs_to :journal, :class => 'CortexReaver::Journal'
11
+ belongs_to :project, :class => 'CortexReaver::Project'
12
+ belongs_to :photograph, :class => 'CortexReaver::Photograph'
13
+ belongs_to :page, :class => 'CortexReaver::Page'
14
+ belongs_to :comment, :class => 'CortexReaver::Comment'
15
+ has_many :comments, :class => 'CortexReaver::Comment'
16
+
17
+ validates do
18
+ presence_of :body
19
+ length_of :title, :maximum => 255, :allow_nil => true
20
+ length_of :name, :maximum => 255, :allow_nil => true
21
+ length_of :http, :maximum => 255, :allow_nil => true
22
+ length_of :email, :maximum => 255, :allow_nil => true
23
+ format_of :email,
24
+ :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/, :allow_nil => true
25
+ end
26
+
27
+ # Ensure comments with an email specified do *not* conflict with another user.
28
+ validates_each :email do |object, attribute, value|
29
+ if (not value.blank?) and User.filter(:email => value).count > 0
30
+ object.errors[attribute] << 'conflicts with a registered user'
31
+ end
32
+ end
33
+
34
+ # Ensures comments belong to exactly one parent.
35
+ validates_each :page_id do |object, attribute, value|
36
+ count = 0
37
+ [:page_id, :project_id, :journal_id, :comment_id, :photograph_id].each do |field|
38
+ unless object[field].blank?
39
+ count += 1
40
+ if count > 1
41
+ object.errors[attribute] << 'has too many kinds of parents'
42
+ break
43
+ end
44
+ end
45
+ end
46
+
47
+ if count == 0
48
+ object.errors[attribute] << "doesn't have a parent"
49
+ end
50
+ end
51
+
52
+ # Infer blank titles
53
+ before_save(:infer_title) do
54
+ if title.blank?
55
+ title = 'Re: ' + parent.title.to_s
56
+ title.gsub!(/^(Re: )+/, 'Re: ')
57
+ self.title = title
58
+ end
59
+ end
60
+
61
+ # Update parent comment counts
62
+ before_destroy(:decrement_parent_comment_count) do
63
+ parent = self.parent
64
+ parent.comment_count -= 1
65
+ parent.skip_timestamp_update = true
66
+ parent.save
67
+ end
68
+ after_save(:refresh_parent_comment_count) do
69
+ # WARNING: If we *reparent* comments as opposed to just posting, this will break.
70
+ parent = self.parent
71
+ parent.comment_count += 1
72
+ parent.skip_timestamp_update = true
73
+ parent.save
74
+ end
75
+
76
+ render :body, :with => :render_comment
77
+
78
+ def self.get(id)
79
+ self[id]
80
+ end
81
+
82
+ def self.recent
83
+ reverse_order(:created_on).limit(16)
84
+ end
85
+
86
+ def self.url
87
+ '/comments'
88
+ end
89
+
90
+ def self.infer_blank_titles
91
+ self.all.each do |comment|
92
+ if comment.title.blank?
93
+ comment.title = 'Re: ' + comment.parent.title.to_s
94
+ comment.title.gsub!(/^(Re: )+/, 'Re: ')
95
+ comment.skip_timestamp_update = true
96
+ comment.save
97
+ end
98
+ end
99
+ end
100
+
101
+ def url
102
+ root_parent.url + '#comment_' + id.to_s
103
+ end
104
+
105
+ def to_s
106
+ title || 'comment ' + id.to_s
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,53 @@
1
+ module CortexReaver
2
+ class Journal < Sequel::Model(:journals)
3
+ include CortexReaver::Model::Timestamps
4
+ include CortexReaver::Model::CachedRendering
5
+ include CortexReaver::Model::Renderer
6
+ include CortexReaver::Model::Canonical
7
+ include CortexReaver::Model::Attachments
8
+ include CortexReaver::Model::Comments
9
+ include CortexReaver::Model::Tags
10
+ include CortexReaver::Model::Sequenceable
11
+
12
+ many_to_many :tags, :class => 'CortexReaver::Tag'
13
+ belongs_to :user, :class => 'CortexReaver::User'
14
+ has_many :comments, :class => 'CortexReaver::Comment'
15
+
16
+ validates do
17
+ uniqueness_of :name
18
+ presence_of :name
19
+ length_of :name, :maximum => 255
20
+ presence_of :title
21
+ end
22
+
23
+ render :body
24
+
25
+ def self.get(id)
26
+ self[:name => id] || self[id]
27
+ end
28
+
29
+ def self.recent
30
+ reverse_order(:created_on).limit(16)
31
+ end
32
+
33
+ def self.url
34
+ '/journals'
35
+ end
36
+
37
+ def self.atom_url
38
+ '/journals/atom'
39
+ end
40
+
41
+ def atom_url
42
+ '/journals/atom/' + name
43
+ end
44
+
45
+ def url
46
+ '/journals/show/' + name
47
+ end
48
+
49
+ def to_s
50
+ title || name
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,87 @@
1
+ module CortexReaver
2
+ class Page < Sequel::Model(:pages)
3
+ include CortexReaver::Model::Timestamps
4
+ include CortexReaver::Model::CachedRendering
5
+ include CortexReaver::Model::Renderer
6
+ include CortexReaver::Model::Canonical
7
+ include CortexReaver::Model::Attachments
8
+ include CortexReaver::Model::Comments
9
+ include CortexReaver::Model::Tags
10
+ include CortexReaver::Model::Sequenceable
11
+
12
+ belongs_to :user, :class => 'CortexReaver::User'
13
+ has_many :comments, :class => 'CortexReaver::Comment'
14
+ many_to_many :tags, :class => 'CortexReaver::Tag'
15
+
16
+ validates do
17
+ uniqueness_of :name
18
+ presence_of :name
19
+ length_of :name, :maximum => 255
20
+ presence_of :title
21
+ length_of :title, :maximum => 255
22
+
23
+ each(:name, :tag => :url_conflict) do |object, attributes, value|
24
+ if controller = Ramaze::Controller.at(object.url)
25
+ object.errors['name'] << "conflicts with the #{controller}"
26
+ end
27
+ end
28
+ end
29
+
30
+ # Reserve names of controllers so we don't conflict.
31
+ Ramaze::Global.mapping.keys.each do |path|
32
+ path =~ /\/(.+)(\/|$)/
33
+ self.reserved_canonical_names << $1 if $1
34
+ end
35
+
36
+ # Also reserve everything in the public directory, as a courtesy.
37
+ #
38
+ # I can't stop you from shooting yourself in the foot, but this will help you
39
+ # aim higher. :)
40
+ self.reserved_canonical_names += Dir.entries(CortexReaver.config[:public_root]) - ['..', '.']
41
+
42
+ # Use standard cached renderer
43
+ render :body
44
+
45
+ def self.get(id)
46
+ self[:name => id] || self[id]
47
+ end
48
+
49
+ def self.url
50
+ '/'
51
+ end
52
+
53
+ def self.recent
54
+ reverse_order(:updated_on).limit(16)
55
+ end
56
+
57
+ def atom_url
58
+ '/pages/atom/' + name
59
+ end
60
+
61
+ def url
62
+ '/' + name
63
+ end
64
+
65
+ def to_s
66
+ title || name
67
+ end
68
+
69
+ # Create a default page if none exists.
70
+ if table_exists? and Page.count == 0
71
+ Page.new(
72
+ :name => 'about',
73
+ :title => 'About Cortex Reaver',
74
+ :body => <<EOF
75
+ <p>Cortex Reaver is a blog engine designed for managing photographs, projects,
76
+ journal entries, and more, with support for tags, comments, and ratings. Cortex
77
+ Reaver is written in <a href="http://ruby-lang.org">Ruby</a> using <a
78
+ href="http://ramaze.net">Ramaze</a>, uses the <a
79
+ href="http://sequel.rubyforge.org/">Sequel</a> database toolkit and the <a
80
+ href="http://www.kuwata-lab.com/erubis/">Erubis</a> templating engine, and
81
+ makes use of the <a href="http://jquery.com">JQuery</a> JavaScript framework.
82
+ The author is <a href="http://aphyr.com">Aphyr</a>.</p>
83
+ EOF
84
+ ).save
85
+ end
86
+ end
87
+ end