cortex-reaver 0.0.2 → 0.0.3

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.
@@ -24,6 +24,11 @@ module CortexReaver
24
24
  # Parse options
25
25
  @values = {}
26
26
  parser = OptionParser.new do |o|
27
+ o.on '-b', '--blank',
28
+ 'Wipes the database and sets up a clean copy of the latest version.' do
29
+ @action = :blank
30
+ end
31
+
27
32
  o.on '-c', '--config file', 'Configuration file' do |file|
28
33
  self.config_file = file
29
34
  end
@@ -36,38 +41,36 @@ module CortexReaver
36
41
  @action = :help
37
42
  end
38
43
 
39
- o.on '-s', '--start',
40
- 'Start the CortexReaver server.' do
41
- @action = :start
44
+ o.on '-i', '--irb', 'Start an IRB session' do
45
+ @action = :irb
46
+ end
47
+
48
+ o.on '-k', '--stop', 'Stop Cortex Reaver' do
49
+ @action = :stop
42
50
  end
43
51
 
44
52
  o.on '-m', '--migrate [version]',
45
- 'Migrate the database to schema version, or to the latest version.' do |version|
53
+ 'Migrate the database to schema version, or to the latest version' do |version|
46
54
  @action = :migrate
47
55
  @values[:schema_version] = version ? version.to_i : nil
48
56
  end
49
57
 
50
- o.on '-b', '--blank',
51
- 'Wipes the database and sets up a clean copy of the latest version.' do
52
- @action = :blank
53
- end
54
-
55
- o.on '-r', '--restart', 'Restart CortexReaver' do
58
+ o.on '-r', '--restart', 'Restart Cortex Reaver' do
56
59
  @action = :restart
57
60
  end
58
61
 
59
- o.on '-k', '--stop', 'Stop CortexReaver' do
60
- @action = :stop
62
+ o.on '-s', '--start',
63
+ 'Start the Cortex Reaver server' do
64
+ @action = :start
61
65
  end
62
66
 
63
- o.on '--status', 'Check CortexReaver status.' do
67
+ o.on '--status', 'Check Cortex Reaver status' do
64
68
  @action = :status
65
69
  end
66
70
  end
67
71
 
68
72
  parser.parse! ARGV
69
73
 
70
-
71
74
  # Main
72
75
  case @action
73
76
  when :status
@@ -112,11 +115,30 @@ module CortexReaver
112
115
 
113
116
  when :blank
114
117
  if confirm "Are you sure you wish to wipe the database?"
115
- # Strangely, calling Migrator.apply to go down and then up doesn't seem to work. :-/
118
+ # Strangely, calling Migrator.apply to go down and then up doesn't seem
119
+ # to work. :-/
116
120
  system($0, '-f', '-m', '0')
117
121
  system($0, '-f', '-m')
118
122
  end
119
123
 
124
+ when :help
125
+ puts "Cortex Reaver #{APP_VERSION}: A dangerous Ruby blog engine, with a photographic memory."
126
+ puts parser.help
127
+
128
+ when :irb
129
+ # Start an IRB session
130
+ reload_config
131
+ setup
132
+ Ramaze::Global.console = true
133
+
134
+ # Don't let IRB try to interpret our command line
135
+ ARGV.clear
136
+
137
+ require 'irb'
138
+ require 'irb/completion'
139
+
140
+ IRB.start
141
+
120
142
  when :restart
121
143
  restart
122
144
 
@@ -15,11 +15,13 @@ gem install mongrel ramaze sequel yaml erubis BlueCloth rmagick exifr hpricot bu
15
15
  end
16
16
 
17
17
  module CortexReaver
18
+ # Paths
18
19
  ROOT = File.expand_path(__DIR__/'..')
19
20
  LIB_DIR = ROOT/:lib/:cortex_reaver
20
21
  HOME_DIR = Dir.pwd
21
22
 
22
- # We need the configuration class before everything.
23
+ # Some basic initial requirements
24
+ require LIB_DIR/:version
23
25
  require LIB_DIR/:config
24
26
 
25
27
  # Returns the site configuration
@@ -124,6 +126,7 @@ module CortexReaver
124
126
  def self.restart
125
127
  begin
126
128
  stop
129
+ # Wait for Cortex Reaver to finish, and for the port to become available.
127
130
  sleep 5
128
131
  ensure
129
132
  start
@@ -52,12 +52,21 @@ module CortexReaver
52
52
  render_template :list
53
53
  end
54
54
 
55
+ # This action is referenced by public comment-posting forms.
55
56
  def post
56
57
  unless request.post?
57
58
  flash[:error] = "No comment to post!"
58
59
  redirect_to R(:/)
59
60
  end
60
-
61
+
62
+ # Check for robots
63
+ unless request[:captcha].blank? and
64
+ request[:comment].blank?
65
+ # Robot!?
66
+ flash[:error] = "Cortex Reaver is immune to your drivel, spambot."
67
+ redirect R(:/)
68
+ end
69
+
61
70
  begin
62
71
  # Create comment
63
72
  CortexReaver.db.transaction do
@@ -55,7 +55,7 @@ module CortexReaver
55
55
  else
56
56
  # Specific tags
57
57
  @tags = tags
58
- @title = "Tags: #{h tags.join(', ')}"
58
+ @title = "Tags: #{tags.join(', ')}"
59
59
  end
60
60
  end
61
61
 
@@ -56,12 +56,14 @@ module Ramaze
56
56
  # :description => The label for the field (inferred from id by default)
57
57
  # :model => The model to query for fields
58
58
  # :default => The default value for the field (inferred from model and id)
59
+ # :p_class => Class attached to the paragraph
59
60
  def form_p(id, params = {})
60
61
  type = params[:type]
62
+ p_class = params[:p_class]
61
63
  description = params[:description] || id.to_s.titleize
62
64
  model = params[:model]
63
65
  default = params[:default]
64
- if model and not default
66
+ if model and not default and model.respond_to? id
65
67
  default = model.send(id)
66
68
  end
67
69
 
@@ -76,7 +78,7 @@ module Ramaze
76
78
  end
77
79
  end
78
80
 
79
- f = '<p>'
81
+ f = "<p #{p_class.nil? ? '' : 'class="' + attr_h(p_class) + '"'}>"
80
82
  unless type == 'checkbox' or type == 'hidden'
81
83
  f << "<label for=\"#{id}\">#{description}</label>"
82
84
  end
@@ -1,7 +1,7 @@
1
1
  #adminbox {
2
2
  display: none;
3
3
  padding: 0.5em;
4
- margin: 0 0 1em 0;
4
+ margin: -1px 0 1em 0;
5
5
  background-color: #eaeaea;
6
6
  border: 1px solid #aaa;
7
7
  border-top: none;
@@ -9,7 +9,7 @@
9
9
  }
10
10
 
11
11
  #main #adminbox {
12
- margin: -0.8em 0em 1em 0em;
12
+ margin: -1em 0em 1em 0em;
13
13
  }
14
14
 
15
15
  #adminbox .actions-table {
@@ -0,0 +1,24 @@
1
+ code {
2
+ display: block;
3
+ margin: 1em 0;
4
+ padding: 4pt;
5
+ color: #fff;
6
+ background: #000;
7
+ /* white-space: pre */
8
+ }
9
+
10
+ code .r { color: #FCE94F; font-weight: bolder; }
11
+ code .cl { color: #8AE234; font-weight: bolder;}
12
+ code .c { color: #34E2E2; }
13
+ code .dl { color: #EF2929; font-weight: bolder; }
14
+ code .k { color: #AD7FA8; font-weight: bolder; }
15
+ code .i { color: #AD7FA8; font-weight: bolder; }
16
+ code .fu { color: #729FCF; font-weight: bolder; }
17
+ code .co { color: #8AE234; font-weight: bolder; }
18
+ code .ch { color: #AD7FA8; font-weight: bolder; }
19
+ code .idl { color: #EF2929; }
20
+ code .gv { color: #34E2E2; font-weight: bolder; }
21
+ code .pc { color: #AD7FA8; font-weight: bolder; }
22
+ code .sy { color: #AD7FA8; font-weight: bolder; }
23
+ code .fl { color: #AD7FA8; font-weight: bolder; }
24
+
@@ -244,6 +244,10 @@ th {
244
244
  clear: both;
245
245
  }
246
246
 
247
+ .dont-read-me {
248
+ display: none;
249
+ }
250
+
247
251
  .current {
248
252
  font-weight: bolder;
249
253
  }
@@ -1,15 +1,16 @@
1
1
  module CortexReaver
2
2
  module Model
3
- # Some common rendering methods, wrapped up for your convenience. Use in your model
4
- # with something like:
3
+ # Some common rendering methods, wrapped up for your convenience. Use in
4
+ # your model with something like:
5
5
  #
6
6
  # render :body, :with => :render_comment
7
7
  #
8
8
  # See CortexReaver::Model::CachedRendering for more details.
9
9
  module Renderer
10
+
10
11
  require 'bluecloth'
11
12
  require 'hpricot'
12
- require 'syntax'
13
+ require 'coderay'
13
14
 
14
15
  # Elements to allow in sanitized HTML.
15
16
  ELEMENTS = [
@@ -35,11 +36,44 @@ module CortexReaver
35
36
  PROTOCOLS = ['ftp', 'http', 'https', 'mailto']
36
37
 
37
38
 
38
- # Renders plain text and html to html.
39
- def bluecloth(text)
39
+ # Renders plain text and html to html. If parse_code isn't true, only
40
+ # runs bluecloth on text *outside* any <code>...</code> blocks.
41
+ def bluecloth(text, parse_code = true)
40
42
  return text if text.nil?
41
43
 
42
- BlueCloth::new(text).to_html
44
+ if parse_code
45
+ return BlueCloth::new(text).to_html
46
+ end
47
+
48
+ text = text.dup
49
+ out = ''
50
+ level = 0
51
+ until text.empty? do
52
+ if level < 1
53
+ # Find start of code block
54
+ j = text.index('<code>') || text.length
55
+ j -= 1 if j != 0
56
+ level += 1
57
+
58
+ if j != 0
59
+ # Convert to bluecloth
60
+ out << BlueCloth::new(text[0..j]).to_html
61
+ end
62
+ else
63
+ # Find end of code block
64
+ j = text.index('</code>') || text.length
65
+ level -= 1
66
+ j += 6
67
+
68
+ # Output as is
69
+ out << text[0..j]
70
+ end
71
+
72
+ # Excise parsed string
73
+ text.slice! 0..j unless j == 0
74
+ end
75
+
76
+ out
43
77
  end
44
78
 
45
79
  # Replace <% and %> to prevent Erubis injection.
@@ -54,7 +88,9 @@ module CortexReaver
54
88
 
55
89
  # Macro substitutions
56
90
  #
57
- # Expands [[type:resource][name]] macros. Right now, resource is just an attachment.
91
+ # Expands [[type:resource][name]] macros. Right now, resource is just an
92
+ # attachment.
93
+ #
58
94
  # Included types are:
59
95
  #
60
96
  # url: returns the URL to an attachment
@@ -113,10 +149,25 @@ module CortexReaver
113
149
  def syntax_highlight(text)
114
150
  return text if text.nil?
115
151
 
116
- h = Hpricot(text)
152
+ text.gsub(/<cr:code\s.*?(lang="(.*?)").*?>(.*?)<\/cr:code>/m) do |match|
153
+ lang = $2
154
+ code = $3
155
+
156
+ # Replace entities
157
+ code.gsub!('&', '&quot;')
117
158
 
118
- h.search('cr:code').replace do |code|
119
- code[:lang]
159
+ unless lang.empty?
160
+ # Parse with CodeRay.
161
+ code = '<div class="code"><code>' + CodeRay.scan(code, lang.to_sym).html.strip + '</code></div>'
162
+ end
163
+
164
+ # Using white-space: pre is a nice option, but I haven't figured out
165
+ # how to make it work with fluid layouts. So, I'm going with line
166
+ # wrapping and explicit HTML entities; since we're already marking
167
+ # up the code for syntax, might as well go all the way. Plus,
168
+ # this still pastes cleanly, but displays like a terminal.
169
+ code.gsub!("\n", '<br />')
170
+ code.gsub!(/( {2})/) { |match| '&nbsp;' * $1.length }
120
171
  end
121
172
  end
122
173
 
@@ -175,9 +226,11 @@ module CortexReaver
175
226
  bluecloth(
176
227
  macro(
177
228
  erubis_filter(
178
- text
229
+ syntax_highlight(
230
+ text
231
+ )
179
232
  )
180
- )
233
+ ), false
181
234
  ) # (((Feeling) LISPish yet)?)
182
235
  end
183
236
 
@@ -1,6 +1,6 @@
1
1
  module CortexReaver
2
2
  APP_NAME = 'Cortex Reaver'
3
- APP_VERSION = '0.0.2'
3
+ APP_VERSION = '0.0.3'
4
4
  APP_AUTHOR = 'aphyr'
5
5
  APP_EMAIL = 'aphyr@aphyr.com'
6
6
  APP_URL = 'http://aphyr.com'
@@ -18,6 +18,7 @@
18
18
  <link rel="stylesheet" type="text/css" href="/css/photo.css" />
19
19
  <link rel="stylesheet" type="text/css" href="/css/text.css" />
20
20
  <link rel="stylesheet" type="text/css" href="/css/form.css" />
21
+ <link rel="stylesheet" type="text/css" href="/css/code.css" />
21
22
  <link rel="stylesheet" type="text/css" href="/css/custom.css" />
22
23
  <% if defined? feeds %>
23
24
  <% feeds.each do |title, feed| %>
@@ -11,26 +11,32 @@
11
11
  </div>
12
12
  <% end %>
13
13
 
14
- <% if @new_comment.user %>
15
- <%= form_for @new_comment, R(CortexReaver::CommentController, :post), [
16
- :title,
17
- [:body, {:type => 'textarea'}],
18
- [:comment_id, {:type => 'hidden'}],
19
- [:journal_id, {:type => 'hidden'}],
20
- [:photograph_id, {:type => 'hidden'}],
21
- [:project_id, {:type => 'hidden'}]
22
- ] %>
23
- <% else %>
24
- <%= form_for @new_comment, R(CortexReaver::CommentController, :post), [
25
- :title,
26
- :name,
27
- :email,
28
- :http,
29
- [:body, {:type => 'textarea'}],
30
- [:comment_id, {:type => 'hidden'}],
31
- [:journal_id, {:type => 'hidden'}],
32
- [:photograph_id, {:type => 'hidden'}],
33
- [:project_id, {:type => 'hidden'}]
34
- ] %>
35
- <% end %>
14
+ <form class="comment-form" action="<%= R(CortexReaver::CommentController, :post) %>" method="post">
15
+ <%= form_p :title, :model => @new_comment %>
16
+ <p class="dont-read-me">
17
+ Please avoid writing anything here unless you are a computer:
18
+ <label for="captcha">Captcha</label>
19
+ <input type="text" name="captcha" id="captcha" />
20
+
21
+ <br />
22
+ <br />
23
+
24
+ This is also a trap:
25
+ <label for="comment">Comment</label>
26
+ <textarea name="comment" id="comment"></textarea>
27
+ </p>
28
+
29
+ <% unless @new_comment.user %>
30
+ <%= form_p :name, :model => @new_comment %>
31
+ <%= form_p :email, :model => @new_comment %>
32
+ <%= form_p :http, :model => @new_comment %>
33
+ <% end %>
34
+ <%= form_p :body, :type => 'textarea', :model => @new_comment %>
35
+ <%= form_p :comment_id, :type => 'hidden', :model => @new_comment %>
36
+ <%= form_p :journal_id, :type => 'hidden', :model => @new_comment %>
37
+ <%= form_p :photograph_id, :type => 'hidden', :model => @new_comment %>
38
+ <%= form_p :project_id, :type => 'hidden', :model => @new_comment %>
39
+ <%= form_p :page_id, :type => 'hidden', :model => @new_comment %>
40
+ <input type="submit" value="Post Comment" />
41
+ </form>
36
42
  </div>
@@ -18,6 +18,7 @@
18
18
  <link rel="stylesheet" type="text/css" href="/css/photo.css" />
19
19
  <link rel="stylesheet" type="text/css" href="/css/text.css" />
20
20
  <link rel="stylesheet" type="text/css" href="/css/form.css" />
21
+ <link rel="stylesheet" type="text/css" href="/css/code.css" />
21
22
  <link rel="stylesheet" type="text/css" href="/css/custom.css" />
22
23
  <% if @feeds %>
23
24
  <% @feeds.each do |title, feed| %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cortex-reaver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - aphyr
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-16 00:00:00 -08:00
12
+ date: 2008-12-18 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -92,18 +92,25 @@ dependencies:
92
92
  - !ruby/object:Gem::Version
93
93
  version: 0.10.7
94
94
  version:
95
+ - !ruby/object:Gem::Dependency
96
+ name: coderay
97
+ type: :runtime
98
+ version_requirement:
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 0.8.260
104
+ version:
95
105
  description:
96
106
  email: aphyr@aphyr.com
97
107
  executables:
98
108
  - cortex_reaver
99
- - console
100
109
  extensions: []
101
110
 
102
111
  extra_rdoc_files: []
103
112
 
104
113
  files:
105
- - bin/import.rb
106
- - bin/console
107
114
  - bin/cortex_reaver
108
115
  - lib/proto
109
116
  - lib/proto/cortex_reaver.yaml
@@ -230,6 +237,7 @@ files:
230
237
  - lib/cortex_reaver/public/css/form.css
231
238
  - lib/cortex_reaver/public/css/ramaze_error.css
232
239
  - lib/cortex_reaver/public/css/custom.css
240
+ - lib/cortex_reaver/public/css/code.css
233
241
  - lib/cortex_reaver/public/css/photo.css
234
242
  - lib/cortex_reaver/public/css/admin.css
235
243
  - lib/cortex_reaver/public/css/main.css
@@ -1,11 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- require File.dirname(__FILE__) + '/../lib/cortex_reaver'
4
- require 'irb'
5
-
6
- CortexReaver.setup ARGV.first
7
- include CortexReaver
8
-
9
- # Don't let ARGV hit IRB, or it will try to run it!
10
- ARGV.clear
11
- IRB.start
@@ -1,78 +0,0 @@
1
- #!/usr/bin/ruby
2
-
3
- puts `#{File.dirname(__FILE__)}/cortex_reaver -rf #{ARGV.first}`
4
-
5
- require File.dirname(__FILE__) + '/../lib/cortex_reaver'
6
-
7
- CortexReaver.setup ARGV.first
8
-
9
- c = Sequel.connect('mysql://cortex_reaver:RyReajOuc7@localhost/cortex_reaver')
10
- f = Sequel.connect('mysql://cortex_reaver:RyReajOuc7@localhost/fiachran')
11
-
12
- # Journals
13
- puts "Journals..."
14
- f[:journals].each do |journal|
15
- journal[:user_id] = journal.delete :author_id
16
- journal[:name] = Journal.canonicalize journal[:title]
17
- c[:journals] << journal
18
- end
19
-
20
- # Projects
21
- puts "Projects..."
22
- f[:projects].each do |project|
23
- project[:user_id] = project.delete :author_id
24
- project[:name] = Project.canonicalize project[:title]
25
- c[:projects] << project
26
- end
27
-
28
- # Photos
29
- puts "Photographs..."
30
- f[:photographs].each do |photograph|
31
- photograph[:user_id] = photograph.delete :author_id
32
- photograph[:name] = Photograph.canonicalize photograph[:title]
33
- c[:photographs] << photograph
34
- end
35
-
36
- # Comments
37
- puts "Comments..."
38
- f[:comments].each do |comment|
39
- if comment[:email] == 'aphyr@aphyr.com'
40
- comment[:user_id] = 1
41
- end
42
- comment[:name] = comment.delete :author
43
- c[:comments] << comment
44
- end
45
-
46
- # Tags
47
- puts "Tags..."
48
- f[:tags].each do |tag|
49
- tag[:title] = tag[:name]
50
- tag[:name] = Tag.canonicalize tag[:name]
51
- c[:tags] << tag
52
- end
53
-
54
- [:journals_tags, :projects_tags, :photographs_tags].each do |t|
55
- f[t].each do |r|
56
- c[t] << r
57
- end
58
- end
59
-
60
-
61
- puts "Fixing blank comment titles"
62
- Comment.infer_blank_titles
63
-
64
- puts "Fixing tag counts"
65
- Tag.filter({:name => ''} | {:title => ''}).all.each do |tag|
66
- tag.delete
67
- end
68
- Tag.refresh_counts
69
-
70
- puts "Refreshing comment counts..."
71
- Journal.refresh_comment_counts
72
- Photograph.refresh_comment_counts
73
- Project.refresh_comment_counts
74
-
75
- puts "Refreshing cached render fields..."
76
- Journal.refresh_render_caches
77
- Project.refresh_render_caches
78
- Comment.refresh_render_caches