aerial 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -1
- data/README.md +23 -28
- data/Rakefile +27 -52
- data/VERSION +1 -1
- data/aerial.gemspec +134 -0
- data/articles/congratulations/congratulations-aerial-is-configured-correctly.article +6 -0
- data/bin/aerial +5 -0
- data/config/config.sample.ru +19 -0
- data/config/config.sample.yml +29 -0
- data/config/config.test.yml +49 -0
- data/config/config.yml +3 -3
- data/config/thin.sample.yml +13 -0
- data/examples/articles/congratulations/congratulations-aerial-is-configured-correctly.article +6 -0
- data/{lib/spec/fixtures → examples}/public/javascripts/application.js +0 -0
- data/{lib/spec/fixtures → examples}/public/javascripts/jquery-1.3.1.min.js +0 -0
- data/{lib/spec/fixtures → examples}/public/javascripts/jquery.template.js +0 -0
- data/{lib/spec/fixtures → examples}/views/article.haml +1 -1
- data/{lib/spec/fixtures → examples}/views/articles.haml +0 -0
- data/{lib/spec/fixtures → examples}/views/comment.haml +1 -1
- data/{lib/spec/fixtures → examples}/views/home.haml +0 -0
- data/{lib/spec/fixtures → examples}/views/layout.haml +1 -1
- data/examples/views/not_found.haml +1 -0
- data/{lib/spec/fixtures → examples}/views/post.haml +0 -0
- data/{lib/spec/fixtures → examples}/views/rss.haml +2 -2
- data/{lib/spec/fixtures → examples}/views/sidebar.haml +8 -0
- data/{lib/spec/fixtures → examples}/views/style.sass +0 -0
- data/{lib/features → features}/article.feature +0 -0
- data/features/home.feature +16 -0
- data/{lib/features → features}/step_definitions/article_steps.rb +0 -0
- data/{lib/features → features}/step_definitions/home_steps.rb +0 -0
- data/{lib/features → features}/support/env.rb +0 -0
- data/{lib/features → features}/support/pages/article.rb +0 -0
- data/{lib/features → features}/support/pages/homepage.rb +0 -0
- data/index.html +164 -0
- data/lib/aerial.rb +38 -87
- data/lib/aerial/app.rb +93 -0
- data/lib/aerial/article.rb +28 -30
- data/lib/aerial/base.rb +24 -32
- data/lib/aerial/comment.rb +10 -19
- data/lib/aerial/content.rb +12 -21
- data/lib/aerial/installer.rb +119 -0
- data/public/javascripts/application.js +109 -0
- data/public/javascripts/jquery-1.3.1.min.js +19 -0
- data/public/javascripts/jquery.template.js +255 -0
- data/spec/aerial_spec.rb +19 -0
- data/{lib/spec/aerial_spec.rb → spec/app_spec.rb} +32 -40
- data/{lib/spec → spec}/article_spec.rb +21 -21
- data/{lib/spec → spec}/base_spec.rb +1 -5
- data/{lib/spec → spec}/comment_spec.rb +8 -8
- data/{lib/spec → spec}/config_spec.rb +0 -0
- data/spec/fixtures/articles/congratulations-aerial-is-configured-correctly/congratulations-aerial-is-configured-correctly.article +6 -0
- data/spec/fixtures/articles/sample-article/sample-article.article +6 -0
- data/spec/fixtures/articles/test-article-one/test-article.article +7 -0
- data/spec/fixtures/articles/test-article-three/test-article.article +7 -0
- data/spec/fixtures/articles/test-article-two/comment-missing-fields.comment +8 -0
- data/spec/fixtures/articles/test-article-two/test-article.article +7 -0
- data/spec/fixtures/articles/test-article-two/test-comment.comment +10 -0
- data/{lib/spec → spec}/fixtures/config.yml +0 -0
- data/spec/fixtures/public/javascripts/application.js +109 -0
- data/spec/fixtures/public/javascripts/jquery-1.3.1.min.js +19 -0
- data/spec/fixtures/public/javascripts/jquery.template.js +255 -0
- data/spec/fixtures/views/article.haml +19 -0
- data/spec/fixtures/views/articles.haml +2 -0
- data/spec/fixtures/views/comment.haml +8 -0
- data/spec/fixtures/views/home.haml +2 -0
- data/spec/fixtures/views/layout.haml +22 -0
- data/spec/fixtures/views/not_found.haml +1 -0
- data/spec/fixtures/views/post.haml +27 -0
- data/spec/fixtures/views/rss.haml +15 -0
- data/spec/fixtures/views/sidebar.haml +29 -0
- data/spec/fixtures/views/style.sass +163 -0
- data/{lib/spec → spec}/spec_helper.rb +15 -3
- data/views/article.haml +19 -0
- data/views/articles.haml +2 -0
- data/views/comment.haml +8 -0
- data/views/home.haml +2 -0
- data/views/layout.haml +22 -0
- data/views/not_found.haml +1 -0
- data/views/post.haml +27 -0
- data/views/rss.haml +15 -0
- data/views/sidebar.haml +29 -0
- data/views/style.sass +163 -0
- metadata +86 -40
- data/lib/features/home.feature +0 -16
- data/lib/spec/fixtures/articles/sample-article/sample-article.article +0 -6
- data/lib/spec/fixtures/articles/test-article-one/test-article.article +0 -7
- data/lib/spec/fixtures/articles/test-article-three/test-article.article +0 -7
- data/lib/spec/fixtures/articles/test-article-two/comment-missing-fields.comment +0 -8
- data/lib/spec/fixtures/articles/test-article-two/test-article.article +0 -7
- data/lib/spec/fixtures/articles/test-article-two/test-comment.comment +0 -10
data/config/config.yml
CHANGED
@@ -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: "
|
8
|
+
dir: "articles"
|
9
9
|
|
10
10
|
public:
|
11
11
|
dir: "public"
|
12
12
|
|
13
13
|
views:
|
14
|
-
dir: "
|
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.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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 => "
|
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.
|
File without changes
|
@@ -2,7 +2,7 @@
|
|
2
2
|
%rss{"version" => "2.0"}
|
3
3
|
%channel
|
4
4
|
%title= "#{Aerial.config.title}"
|
5
|
-
%link= "
|
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.
|
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|
|
File without changes
|
File without changes
|
@@ -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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/index.html
ADDED
@@ -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>
|
data/lib/aerial.rb
CHANGED
@@ -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
|