aerial 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.gitignore +4 -1
  2. data/README.md +23 -28
  3. data/Rakefile +27 -52
  4. data/VERSION +1 -1
  5. data/aerial.gemspec +134 -0
  6. data/articles/congratulations/congratulations-aerial-is-configured-correctly.article +6 -0
  7. data/bin/aerial +5 -0
  8. data/config/config.sample.ru +19 -0
  9. data/config/config.sample.yml +29 -0
  10. data/config/config.test.yml +49 -0
  11. data/config/config.yml +3 -3
  12. data/config/thin.sample.yml +13 -0
  13. data/examples/articles/congratulations/congratulations-aerial-is-configured-correctly.article +6 -0
  14. data/{lib/spec/fixtures → examples}/public/javascripts/application.js +0 -0
  15. data/{lib/spec/fixtures → examples}/public/javascripts/jquery-1.3.1.min.js +0 -0
  16. data/{lib/spec/fixtures → examples}/public/javascripts/jquery.template.js +0 -0
  17. data/{lib/spec/fixtures → examples}/views/article.haml +1 -1
  18. data/{lib/spec/fixtures → examples}/views/articles.haml +0 -0
  19. data/{lib/spec/fixtures → examples}/views/comment.haml +1 -1
  20. data/{lib/spec/fixtures → examples}/views/home.haml +0 -0
  21. data/{lib/spec/fixtures → examples}/views/layout.haml +1 -1
  22. data/examples/views/not_found.haml +1 -0
  23. data/{lib/spec/fixtures → examples}/views/post.haml +0 -0
  24. data/{lib/spec/fixtures → examples}/views/rss.haml +2 -2
  25. data/{lib/spec/fixtures → examples}/views/sidebar.haml +8 -0
  26. data/{lib/spec/fixtures → examples}/views/style.sass +0 -0
  27. data/{lib/features → features}/article.feature +0 -0
  28. data/features/home.feature +16 -0
  29. data/{lib/features → features}/step_definitions/article_steps.rb +0 -0
  30. data/{lib/features → features}/step_definitions/home_steps.rb +0 -0
  31. data/{lib/features → features}/support/env.rb +0 -0
  32. data/{lib/features → features}/support/pages/article.rb +0 -0
  33. data/{lib/features → features}/support/pages/homepage.rb +0 -0
  34. data/index.html +164 -0
  35. data/lib/aerial.rb +38 -87
  36. data/lib/aerial/app.rb +93 -0
  37. data/lib/aerial/article.rb +28 -30
  38. data/lib/aerial/base.rb +24 -32
  39. data/lib/aerial/comment.rb +10 -19
  40. data/lib/aerial/content.rb +12 -21
  41. data/lib/aerial/installer.rb +119 -0
  42. data/public/javascripts/application.js +109 -0
  43. data/public/javascripts/jquery-1.3.1.min.js +19 -0
  44. data/public/javascripts/jquery.template.js +255 -0
  45. data/spec/aerial_spec.rb +19 -0
  46. data/{lib/spec/aerial_spec.rb → spec/app_spec.rb} +32 -40
  47. data/{lib/spec → spec}/article_spec.rb +21 -21
  48. data/{lib/spec → spec}/base_spec.rb +1 -5
  49. data/{lib/spec → spec}/comment_spec.rb +8 -8
  50. data/{lib/spec → spec}/config_spec.rb +0 -0
  51. data/spec/fixtures/articles/congratulations-aerial-is-configured-correctly/congratulations-aerial-is-configured-correctly.article +6 -0
  52. data/spec/fixtures/articles/sample-article/sample-article.article +6 -0
  53. data/spec/fixtures/articles/test-article-one/test-article.article +7 -0
  54. data/spec/fixtures/articles/test-article-three/test-article.article +7 -0
  55. data/spec/fixtures/articles/test-article-two/comment-missing-fields.comment +8 -0
  56. data/spec/fixtures/articles/test-article-two/test-article.article +7 -0
  57. data/spec/fixtures/articles/test-article-two/test-comment.comment +10 -0
  58. data/{lib/spec → spec}/fixtures/config.yml +0 -0
  59. data/spec/fixtures/public/javascripts/application.js +109 -0
  60. data/spec/fixtures/public/javascripts/jquery-1.3.1.min.js +19 -0
  61. data/spec/fixtures/public/javascripts/jquery.template.js +255 -0
  62. data/spec/fixtures/views/article.haml +19 -0
  63. data/spec/fixtures/views/articles.haml +2 -0
  64. data/spec/fixtures/views/comment.haml +8 -0
  65. data/spec/fixtures/views/home.haml +2 -0
  66. data/spec/fixtures/views/layout.haml +22 -0
  67. data/spec/fixtures/views/not_found.haml +1 -0
  68. data/spec/fixtures/views/post.haml +27 -0
  69. data/spec/fixtures/views/rss.haml +15 -0
  70. data/spec/fixtures/views/sidebar.haml +29 -0
  71. data/spec/fixtures/views/style.sass +163 -0
  72. data/{lib/spec → spec}/spec_helper.rb +15 -3
  73. data/views/article.haml +19 -0
  74. data/views/articles.haml +2 -0
  75. data/views/comment.haml +8 -0
  76. data/views/home.haml +2 -0
  77. data/views/layout.haml +22 -0
  78. data/views/not_found.haml +1 -0
  79. data/views/post.haml +27 -0
  80. data/views/rss.haml +15 -0
  81. data/views/sidebar.haml +29 -0
  82. data/views/style.sass +163 -0
  83. metadata +86 -40
  84. data/lib/features/home.feature +0 -16
  85. data/lib/spec/fixtures/articles/sample-article/sample-article.article +0 -6
  86. data/lib/spec/fixtures/articles/test-article-one/test-article.article +0 -7
  87. data/lib/spec/fixtures/articles/test-article-three/test-article.article +0 -7
  88. data/lib/spec/fixtures/articles/test-article-two/comment-missing-fields.comment +0 -8
  89. data/lib/spec/fixtures/articles/test-article-two/test-article.article +0 -7
  90. data/lib/spec/fixtures/articles/test-article-two/test-comment.comment +0 -10
@@ -1,17 +1,17 @@
1
- title: ""
1
+ title: "Aerial"
2
2
  subtitle: ""
3
3
  name: ""
4
4
  author: ""
5
5
  email: ""
6
6
 
7
7
  articles:
8
- dir: "app/articles"
8
+ dir: "articles"
9
9
 
10
10
  public:
11
11
  dir: "public"
12
12
 
13
13
  views:
14
- dir: "app/views"
14
+ dir: "views"
15
15
  default: "home"
16
16
 
17
17
  akismet:
@@ -0,0 +1,13 @@
1
+ ---
2
+ environment: development
3
+ chdir: /apps/aerial
4
+ address: 127.0.0.1
5
+ port: 4567
6
+ pid: /apps/aerial/thin.pid
7
+ rackup: /apps/aerial/config.ru
8
+ log: /apps/aerial/log/thin.log
9
+ max_conns: 1024
10
+ timeout: 30
11
+ max_persistent_conns: 512
12
+ daemonize: false
13
+ servers: 1
@@ -0,0 +1,6 @@
1
+ Title : Congratulations! Aerial is configured correctly
2
+ Tags : ruby, sinatra, git, aerial
3
+ Publish Date : 03/31/2009
4
+ Author : Aerial
5
+
6
+ Congratulations! Aerial appears to be up and running. This is a sample article created during the bootstrap process. You may overwrite this article or create a new one.
@@ -6,7 +6,7 @@
6
6
  %span
7
7
  =article.comments.size
8
8
  %h3
9
- ="Posted by #{article.author} on #{humanized_date article.published_at}"
9
+ ="Posted by #{article.author} on #{humanized_date article.publish_date}"
10
10
  %p.entry
11
11
  =article.body_html
12
12
  .meta
@@ -3,6 +3,6 @@
3
3
  %a{:href => comment.homepage}
4
4
  =comment.author
5
5
  %span
6
- =comment.published_at
6
+ =comment.publish_date
7
7
  %p
8
8
  =comment.body
@@ -6,7 +6,7 @@
6
6
  %script{ 'type' => "text/javascript", :src => "/javascripts/jquery.template.js" }
7
7
  %script{ 'type' => "text/javascript", :src => "/javascripts/application.js" }
8
8
  %link{:href => '/style.css', :rel => 'stylesheet', :type => 'text/css'}
9
- %link{:href => "http://#{hostname}/feed", :rel => 'alternate', :type => 'application/atom+xml', :title => "Feed for #{}" }
9
+ %link{:href => "#{base_url}/feed", :rel => 'alternate', :type => 'application/atom+xml', :title => "Feed for #{}" }
10
10
  %body
11
11
  #container
12
12
  #header
@@ -0,0 +1 @@
1
+ The page you requested could not be found.
@@ -2,7 +2,7 @@
2
2
  %rss{"version" => "2.0"}
3
3
  %channel
4
4
  %title= "#{Aerial.config.title}"
5
- %link= "http://#{hostname}"
5
+ %link= "#{base_url}"
6
6
  %language= "en-us"
7
7
  %ttl= "40"
8
8
  %description= "#{Aerial.config.subtitle}"
@@ -11,5 +11,5 @@
11
11
  %title= article.title
12
12
  %link= full_hostname(article.permalink)
13
13
  %description= article.body_html
14
- %pubDate= article.published_at
14
+ %pubDate= article.publish_date
15
15
  %guid{"isPermaLink" => "false"}= article.id
@@ -4,6 +4,14 @@
4
4
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
5
5
  labore et dolore magna aliqua. Ut enimad minim veniam, quis nostrud exercitation ullamco
6
6
  laboris nisi ut aliquip ex ea commodo consequat.
7
+
8
+ #menu
9
+ %h2 Menu
10
+ %ul
11
+ %li
12
+ %a{:href => "/"}Home
13
+ %li
14
+ %a{:href => "/about"}About
7
15
  %h2 Recent Posts
8
16
  %ul
9
17
  -Aerial::Article.recent.each do |article|
@@ -0,0 +1,16 @@
1
+ Feature: Homepage
2
+ In order to view recent Articles
3
+ As anonymous
4
+ wants to view the most recent articles
5
+
6
+ Scenario: Opening the home page
7
+ Given there are articles
8
+ When I view the Homepage
9
+ Then the title should be "Aerial | A Microblog by Matt Sears"
10
+ Then I should see "Congratulations! Aerial is configured correctly"
11
+ Then I should see a link to "Home":/home
12
+ Then I should see a link to "About":/about
13
+ Then I should see a link to "ruby":/tags/ruby
14
+ Then I should see a link to "sinatra":/tags/sinatra
15
+ Then I should see a link to "git":/tags/git
16
+ Then I should see a link to "aerial":/tags/aerial
@@ -0,0 +1,164 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
7
+ <title>aerial</title>
8
+ <style type="text/css">
9
+ /* reset */
10
+ html, body, div, span, applet, object, iframe,
11
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
12
+ a, abbr, acronym, address, big, cite, code,
13
+ del, dfn, em, font, img, ins, kbd, q, s, samp,
14
+ small, strike, strong, sub, sup, tt, var,
15
+ dl, dt, dd, ul, li,
16
+ form, label, legend,
17
+ table, caption, tbody, tfoot, thead, tr, th, td {
18
+ margin: 0;
19
+ padding: 0;
20
+ border: 0;
21
+ outline: 0;
22
+ font-weight: inherit;
23
+ font-style: normal;
24
+ font-size: 100%;
25
+ font-family: inherit;
26
+ vertical-align: baseline;
27
+ }
28
+ :focus {
29
+ outline: 0;
30
+ }
31
+ body {
32
+ line-height: 1;
33
+ color: black;
34
+ background: white;
35
+ }
36
+ ul {
37
+ list-style: none;
38
+ }
39
+ table {
40
+ border-collapse: collapse;
41
+ border-spacing: 0;
42
+ }
43
+ caption, th, td {
44
+ text-align: left;
45
+ font-weight: normal;
46
+ }
47
+ blockquote:before, blockquote:after,
48
+ q:before, q:after {
49
+ content: "";
50
+ }
51
+ blockquote, q {
52
+ quotes: "" "";
53
+ }
54
+
55
+ /* styles */
56
+ body {
57
+ font-family: Verdana,Arial,sans-serif;
58
+ background: #f0f0f0;
59
+ color: #333;
60
+ }
61
+ #inset {
62
+ margin: 0 auto;
63
+ width: 860px;
64
+ }
65
+ #container {
66
+ background-color: #fff;
67
+ color: #000;
68
+ padding: 50px 100px;
69
+ }
70
+ p, h2 {
71
+ margin: 20px 0;
72
+ }
73
+ p {
74
+ line-height: 20px;
75
+ }
76
+ a {
77
+ color: #000;
78
+ text-decoration: none;
79
+ font-weight: bold;
80
+ }
81
+ a:hover {
82
+ color: #26B3CF;
83
+ }
84
+ h1 {
85
+ /* Hide generated title */
86
+ display: none;
87
+ }
88
+ h1.title {
89
+ display: block;
90
+ font-size: 3.8em;
91
+ margin-bottom: 3px;
92
+ }
93
+ h1.title .small {
94
+ font-size: 0.4em;
95
+ }
96
+ h1 a {
97
+ font-weight: normal;
98
+ }
99
+ h2 {
100
+ font-size: 1.5em;
101
+ }
102
+ li {
103
+ padding-bottom: 10px;
104
+ }
105
+ .ribbon {
106
+ float: right;
107
+ }
108
+ .description {
109
+ font-size: 1.2em;
110
+ margin-bottom: 30px;
111
+ margin-top: 30px;
112
+ font-style: italic;
113
+ }
114
+ pre {
115
+ background: #444;
116
+ color: #fff;
117
+ font-family:'Bitstream Vera Sans Mono','Courier',monospace;
118
+ padding: 15px;
119
+ -moz-border-radius: 5px;
120
+ -webkit-border-radius: 5px;
121
+ }
122
+ </style>
123
+ </head>
124
+ <body>
125
+ <div id="inset">
126
+ <a href="http://github.com/mattsears/aerial">
127
+ <img class="ribbon" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" />
128
+ </a>
129
+ <div id="container">
130
+ <div class="description">
131
+ Aerial uses Git to store articles and pages.
132
+ </div>
133
+ <h1>Aerial</h1>
134
+ <p>Designed for Ruby developers, there is no admin interface and no SQL database. Articles are written in your favorite text editor and versioned with Git. Comments are also stored as plain-text files and pushed to the remote repository when created. It uses Grit (http://github.com/mojombo/grit) to interface with local and remote Git repositories.</p>
135
+ <h2>Installation</h2>
136
+
137
+ <p>via Rubygems:</p>
138
+ <pre><code>$ gem install aerial
139
+ $ aerial install /home/user/myblog</code></pre>
140
+ <p>This will create a couple files and directories. Mainly, the views, public, and configuration files. You may edit config.yml to your liking</p>
141
+ <p>The installer provides special configuration files for Thin and Passenger.</p>
142
+ <p>via Clone:</p>
143
+ <pre><code>$ git clone git://github.com/mattsears/aerial</code></pre>
144
+
145
+ <h2>Pasenger</h2>
146
+ <pre><code>$ aerial install /home/user/myblog --passenger
147
+ $ cd /home/user/myblog</code></pre>
148
+ <p>Then, restart Passenger <b>$ touch tmp/restart.txt</b></p>
149
+ <h2>Thin</h2>
150
+ <p>Install Thin:</p>
151
+ <pre><code>$ gem install thin</code></pre>
152
+ <p>Run the installer:</p>
153
+ <pre><code>$ aerial install /home/user/myblog --thin
154
+ $ cd /home/user/myblog</code></pre>
155
+ <p>Tweak the thin.yml</p>
156
+ <p>Start the thin server</p>
157
+ <pre><code>$ thin -C thin.yml -R config.ru start</code></pre>
158
+ <h2>Issues</h2>
159
+ <p>Find a bug? Want a feature? Submit an <a href="http://github.com/mattsears/aerial/issues">issue here</a>. Patches welcome!
160
+ </p
161
+ </div>
162
+ </div>
163
+ </body>
164
+ </html>
@@ -1,100 +1,51 @@
1
1
  libdir = File.dirname(__FILE__)
2
2
  $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
3
  AERIAL_ROOT = File.join(File.dirname(__FILE__), '..') unless defined? AERIAL_ROOT
4
+ CONFIG = YAML.load_file( File.join(AERIAL_ROOT, 'config', 'config.yml') ) unless defined?(CONFIG)
4
5
 
5
6
  # System requirements
6
7
  require 'rubygems'
7
8
  require 'grit'
8
9
  require 'yaml'
9
10
  require 'sinatra'
11
+ require 'haml'
12
+ require 'sass'
10
13
  require 'rdiscount'
11
14
  require 'aerial/base'
15
+ require 'aerial/content'
16
+ require 'aerial/article'
17
+ require 'aerial/comment'
18
+ require 'aerial/vendor/cache'
19
+ require 'aerial/vendor/akismetor'
20
+ require 'aerial/config'
21
+ require 'aerial/app'
22
+
23
+ module Aerial
24
+
25
+ # Make sure git is added to the env path
26
+ ENV['PATH'] = "#{ENV['PATH']}:/usr/local/bin"
27
+ VERSION = '0.1.0'
28
+
29
+ class << self
30
+ attr_accessor :debug, :logger, :repo, :config
31
+ end
32
+
33
+ def self.new(root, config_name = nil)
34
+ @root ||= root
35
+ @logger ||= ::Logger.new(STDOUT)
36
+ @debug ||= false
37
+ @repo ||= Grit::Repo.new(@root)
38
+ config = File.join(root, config_name)
39
+
40
+ if config.is_a?(String) && File.file?(config)
41
+ @config = Aerial::Config.new(YAML.load_file(config))
42
+ elsif config.is_a?(Hash)
43
+ @config = Aerial::Config.new(config)
44
+ end
45
+ end
46
+
47
+ def self.log(str)
48
+ logger.debug { str } if debug
49
+ end
12
50
 
13
- before do
14
- # kill trailing slashes for all requests except '/'
15
- request.env['PATH_INFO'].gsub!(/\/$/, '') if request.env['PATH_INFO'] != '/'
16
- end
17
-
18
- # Configuration
19
- configure do
20
- set :views => Aerial.config.theme_directory
21
- set :public => Aerial.config.public.dir
22
- end
23
-
24
- # Helpers
25
- helpers do
26
- include Rack::Utils
27
- include Sinatra::Cache::Helpers
28
- include Aerial::Helper
29
- alias_method :h, :escape_html
30
- end
31
-
32
- # Homepage
33
- get '/' do
34
- @articles = Aerial::Article.recent(:limit => 10)
35
- cache haml(Aerial.config.views.default.to_sym)
36
- end
37
-
38
- # Articles
39
- get '/articles' do
40
- @content_for_sidebar = partial(:sidebar)
41
- @articles = Aerial::Article.recent(:limit => 10)
42
- cache haml(:articles)
43
- end
44
-
45
- get '/feed*' do
46
- content_type 'text/xml', :charset => 'utf-8'
47
- @articles = Aerial::Article.all
48
- cache haml(:rss, :layout => false)
49
- end
50
-
51
- # Sassy!
52
- get '/style.css' do
53
- content_type 'text/css', :charset => 'utf-8'
54
- cache sass(:style)
55
- end
56
-
57
- # Single page
58
- get '/:page' do
59
- cache haml(params[:page])
60
- end
61
-
62
- # Single article page
63
- get '/:year/:month/:day/:article' do
64
- link = [params[:year], params[:month], params[:day], params[:article]].join("/")
65
- @content_for_sidebar = partial(:sidebar)
66
- @article = Aerial::Article.with_permalink("/#{link}")
67
- throw :halt, [404, not_found ] unless @article
68
- @page_title = @article.title
69
- cache haml(:post)
70
- end
71
-
72
- # Article tags
73
- get '/tags/:tag' do
74
- @content_for_sidebar = partial(:sidebar)
75
- @articles = Aerial::Article.with_tag(params[:tag])
76
- cache haml(:articles)
77
- end
78
-
79
- # Article archives
80
- get '/archives/:year/:month' do
81
- @content_for_sidebar = partial(:sidebar)
82
- @articles = Aerial::Article.with_date(params[:year], params[:month])
83
- cache haml(:articles)
84
- end
85
-
86
- # Add comment
87
- post '/article/:id/comments' do
88
- @article = Aerial::Article.find(params[:id])
89
- throw :halt, [404, not_found ] unless @article
90
-
91
- comment = Aerial::Comment.new(params.merge!( {
92
- :referrer => request.referrer,
93
- :user_agent => request.user_agent,
94
- :user_ip => request.ip
95
- }))
96
-
97
- @article.comments << comment.save(@article.archive_name)
98
- cache_expire( @article.permalink )
99
- status 204
100
51
  end