cortex-reaver 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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