postview 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +67 -0
- data/INFO +14 -0
- data/LICENSE +0 -0
- data/README.rdoc +103 -0
- data/Rakefile +174 -0
- data/VERSION +8 -0
- data/bin/postview +51 -0
- data/lib/postview.rb +68 -0
- data/lib/postview/about.rb +34 -0
- data/lib/postview/application.rb +130 -0
- data/lib/postview/cli.rb +71 -0
- data/lib/postview/cli/create_command.rb +362 -0
- data/lib/postview/cli/server_command.rb +115 -0
- data/lib/postview/helpers.rb +21 -0
- data/lib/postview/patches.rb +11 -0
- data/lib/postview/settings.rb +107 -0
- data/lib/postview/site.rb +51 -0
- data/lib/postview/version.rb +27 -0
- data/tasks/documentation.rake +21 -0
- data/tasks/history.rake +7 -0
- data/tasks/homepage.rake +10 -0
- data/tasks/package.rake +11 -0
- data/tasks/version.rake +56 -0
- data/test/application_test.rb +122 -0
- data/test/extensions.rb +23 -0
- data/test/fixtures/application/config.ru +6 -0
- data/test/fixtures/application/config/settings.yml +22 -0
- data/test/fixtures/application/empty.yml +0 -0
- data/test/fixtures/application/posts/20090529-postview_blogware.ruby.sinatra.mkd +4 -0
- data/test/fixtures/application/posts/20090602-postview_blogware.ruby.sinatra.mkd +4 -0
- data/test/fixtures/application/posts/archive/20080529-postview_blogware.ruby.sinatra.mkd +4 -0
- data/test/fixtures/application/posts/archive/20080602-postview_blogware.ruby.sinatra.mkd +4 -0
- data/test/fixtures/application/posts/drafts/20090730-draft_postview_blogware.ruby.sinatra.mkd +4 -0
- data/test/fixtures/application/themes/gemstone/about.erb +0 -0
- data/test/fixtures/application/themes/gemstone/archive/index.erb +0 -0
- data/test/fixtures/application/themes/gemstone/archive/show.erb +17 -0
- data/test/fixtures/application/themes/gemstone/images/banners/banner.jpg +0 -0
- data/test/fixtures/application/themes/gemstone/images/favicon.ico +0 -0
- data/test/fixtures/application/themes/gemstone/images/trojan.com +0 -0
- data/test/fixtures/application/themes/gemstone/index.erb +0 -0
- data/test/fixtures/application/themes/gemstone/javascripts/gemstone.js +1 -0
- data/test/fixtures/application/themes/gemstone/layout.erb +0 -0
- data/test/fixtures/application/themes/gemstone/posts/index.erb +0 -0
- data/test/fixtures/application/themes/gemstone/posts/show.erb +0 -0
- data/test/fixtures/application/themes/gemstone/search.erb +0 -0
- data/test/fixtures/application/themes/gemstone/stylesheets/gemstone.css +1 -0
- data/test/fixtures/application/themes/gemstone/tags/index.erb +0 -0
- data/test/fixtures/application/themes/gemstone/tags/show.erb +0 -0
- data/test/helper.rb +9 -0
- data/test/settings_test.rb +72 -0
- data/test/site_test.rb +62 -0
- data/themes/default/about.erb +24 -0
- data/themes/default/archive/index.erb +21 -0
- data/themes/default/archive/show.erb +17 -0
- data/themes/default/error.erb +0 -0
- data/themes/default/images/favicon.ico +0 -0
- data/themes/default/images/logo.png +0 -0
- data/themes/default/images/navigation-bar.gif +0 -0
- data/themes/default/images/postview.png +0 -0
- data/themes/default/images/rack.png +0 -0
- data/themes/default/images/ruby.png +0 -0
- data/themes/default/images/sinatra.png +0 -0
- data/themes/default/index.erb +38 -0
- data/themes/default/layout.erb +117 -0
- data/themes/default/posts/index.erb +21 -0
- data/themes/default/posts/show.erb +17 -0
- data/themes/default/search.erb +40 -0
- data/themes/default/stylesheets/postview.css +238 -0
- data/themes/default/tags/index.erb +12 -0
- data/themes/default/tags/show.erb +40 -0
- metadata +158 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
module Postview
|
2
|
+
|
3
|
+
Application.class_eval do
|
4
|
+
set :environment, :production
|
5
|
+
end
|
6
|
+
|
7
|
+
module CLI
|
8
|
+
|
9
|
+
# Copying (c) 2009 Hallison Batista
|
10
|
+
class ServerCommand #:nodoc: all
|
11
|
+
|
12
|
+
include Command
|
13
|
+
|
14
|
+
def initialize(path, arguments)
|
15
|
+
@path, @arguments, @options = path, arguments, {}
|
16
|
+
@server_options = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
parse_arguments
|
21
|
+
load_server
|
22
|
+
start_server
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.run(args)
|
26
|
+
if args.first =~ /^\w.*|^\/\w.*/
|
27
|
+
new(args.shift, args.options).run
|
28
|
+
else
|
29
|
+
new(".", args.options).run
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Options for arguments.
|
36
|
+
def options_for(name)
|
37
|
+
{ :help => [ nil, "--help", nil,
|
38
|
+
"Show this message." ],
|
39
|
+
:host => [ "-h", "--host [HOST]", String,
|
40
|
+
"Listen on host (default 0.0.0.0)." ],
|
41
|
+
:port => [ "-p", "--port [PORT]", String,
|
42
|
+
"Use port (default: 9000)." ]
|
43
|
+
}[name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_arguments
|
47
|
+
@arguments.summary_indent = " "
|
48
|
+
@arguments.summary_width = 24
|
49
|
+
@arguments.banner = <<-end_banner.gsub(/^[ ]{6}/, '')
|
50
|
+
#{Postview::Version}
|
51
|
+
|
52
|
+
Usage:
|
53
|
+
#{Postview.name.downcase} server <path> [options]
|
54
|
+
|
55
|
+
end_banner
|
56
|
+
|
57
|
+
@arguments.separator "Server options:"
|
58
|
+
|
59
|
+
@arguments.on(*options_for(:help)) { puts @arguments; exit 0 }
|
60
|
+
@arguments.on(*options_for(:host)) { |host| @options[:Host] = host }
|
61
|
+
@arguments.on(*options_for(:port)) { |port| @options[:Port] = port }
|
62
|
+
|
63
|
+
@arguments.separator ""
|
64
|
+
|
65
|
+
begin
|
66
|
+
@arguments.parse!
|
67
|
+
rescue => error
|
68
|
+
puts error
|
69
|
+
puts @arguments
|
70
|
+
end
|
71
|
+
puts "#{Postview::Version}\n\n"
|
72
|
+
end
|
73
|
+
|
74
|
+
def load_server
|
75
|
+
# This code extracted from Rack binary.
|
76
|
+
start "Loading server" do
|
77
|
+
step { @server ||= "mongrel" }
|
78
|
+
step { @options[:Host] ||= "0.0.0.0" }
|
79
|
+
step { @options[:Port] ||= "9000" }
|
80
|
+
step { @path = Pathname.new(@path) }
|
81
|
+
step { @config = @path.join("config.ru") }
|
82
|
+
step do
|
83
|
+
unless @config.exist?
|
84
|
+
raise "Configuration #{@config} not found"
|
85
|
+
else
|
86
|
+
true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
step { @source = @config.read }
|
90
|
+
step { @source = @source.gsub(/^require[ ]'postview'/,'') }
|
91
|
+
step { @server = Rack::Handler::WEBrick }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# TODO: Improve this method for run server using production environment.
|
96
|
+
def start_server
|
97
|
+
init "Postview starting #{@server} on #{@options[:Host]}:#{@options[:Port]}" do
|
98
|
+
ENV['RACK_ENV'] = "production"
|
99
|
+
config = @config.to_s
|
100
|
+
@postview = eval("Rack::Builder.new{(\n#{@source}\n)}.to_app", nil, config)
|
101
|
+
@application = Rack::Builder.new do |application|
|
102
|
+
use Rack::CommonLogger, STDOUT
|
103
|
+
use Rack::ShowExceptions
|
104
|
+
run application
|
105
|
+
end.to_app
|
106
|
+
end
|
107
|
+
@server.run(@postview, @options)
|
108
|
+
end
|
109
|
+
|
110
|
+
end # class ServerCommand
|
111
|
+
|
112
|
+
end # module CLI
|
113
|
+
|
114
|
+
end # module Postview
|
115
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Postview
|
2
|
+
|
3
|
+
# Copyright (c) 2009 Hallison Batista
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
attr_reader :site, :page
|
7
|
+
attr_reader :post, :posts, :archive, :tag, :tags
|
8
|
+
|
9
|
+
# ...
|
10
|
+
def count_posts_by_tag(tagname)
|
11
|
+
@count_posts_by_tag ||= @tags.inject({}) do |hash, tag|
|
12
|
+
hash[tag] = (@site.find.all_posts + @site.find_archived.all_posts).count{ |post| post.tags.include? tag }
|
13
|
+
hash
|
14
|
+
end
|
15
|
+
@count_posts_by_tag[tagname]
|
16
|
+
end
|
17
|
+
|
18
|
+
end # module Helpers
|
19
|
+
|
20
|
+
end # module Postview
|
21
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Postview
|
2
|
+
|
3
|
+
# Copyright (c) 2009 Hallison Batista
|
4
|
+
class Settings
|
5
|
+
|
6
|
+
DEFAULTS = {
|
7
|
+
:site => {
|
8
|
+
:title => "Postview",
|
9
|
+
:subtitle => "Post your articles",
|
10
|
+
:author => "Hallison Batista",
|
11
|
+
:email => "email@example.com",
|
12
|
+
:domain => "example.com",
|
13
|
+
:directory => "/var/www/example",
|
14
|
+
:theme => "default"
|
15
|
+
},
|
16
|
+
:directories => {
|
17
|
+
:posts => "posts",
|
18
|
+
:archive => "posts/archive",
|
19
|
+
:drafts => "posts/drafts"
|
20
|
+
},
|
21
|
+
:sections => {
|
22
|
+
:root => "/",
|
23
|
+
:posts => "/posts",
|
24
|
+
:tags => "/tags",
|
25
|
+
:archive => "/archive",
|
26
|
+
:drafts => "/drafts",
|
27
|
+
:search => "/search",
|
28
|
+
:about => "/about"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
FILE_NAME = "settings.yml"
|
32
|
+
FILE_DIR = "config"
|
33
|
+
FILE = Postview::PATH.join(FILE_DIR, FILE_NAME)
|
34
|
+
|
35
|
+
attr_reader :site, :theme, :directories, :sections
|
36
|
+
|
37
|
+
def initialize(attributes = {})
|
38
|
+
attributes.symbolize_keys.merge(DEFAULTS) do |key, value, default|
|
39
|
+
value || default
|
40
|
+
end.instance_variables_set_to(self)
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_site
|
44
|
+
build_all_finders_for(Site.new(site))
|
45
|
+
end
|
46
|
+
|
47
|
+
def build_page
|
48
|
+
OpenStruct.new(:title => "", :keywords => [])
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_all_finders_for(site)
|
52
|
+
site.find = build_finder_for(:posts)
|
53
|
+
site.find_archived = build_finder_for(:archive)
|
54
|
+
site.find_drafted = build_finder_for(:drafts)
|
55
|
+
site
|
56
|
+
end
|
57
|
+
|
58
|
+
def build_finder_for(directory)
|
59
|
+
Postage::Finder.new(directory_for(directory))
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.load
|
63
|
+
load_file(FILE)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.load_file(file_name)
|
67
|
+
begin
|
68
|
+
new(YAML.load_file(file_name) || DEFAULTS)
|
69
|
+
rescue Errno::ENOENT
|
70
|
+
new(DEFAULTS)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.load_file_from(path)
|
75
|
+
file = Pathname.new(path).join(FILE_DIR, FILE_NAME)
|
76
|
+
new(YAML.load_file(file))
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.build_default_file
|
80
|
+
FILE.open "w+" do |file|
|
81
|
+
file << DEFAULTS.to_yaml
|
82
|
+
end unless FILE.exist?
|
83
|
+
end
|
84
|
+
|
85
|
+
def file
|
86
|
+
FILE
|
87
|
+
end
|
88
|
+
|
89
|
+
def file_names_for(directory, pattern = "**.*")
|
90
|
+
directory_for(directory, pattern)
|
91
|
+
end
|
92
|
+
|
93
|
+
def directory_for(name, *paths)
|
94
|
+
return Pathname.new(directories[name], *paths) if directories[name].match(%r{^/.*})
|
95
|
+
PATH.join(directories[name], *paths)
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_hash
|
99
|
+
DEFAULTS.keys.inject({}) do |hash, method|
|
100
|
+
hash[method] = send(method)
|
101
|
+
hash
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end # class Settings
|
106
|
+
|
107
|
+
end # module Postview
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Postview
|
2
|
+
|
3
|
+
# Copyright (c) 2009 Hallison Batista
|
4
|
+
class Site
|
5
|
+
|
6
|
+
# Site title.
|
7
|
+
attr_accessor :title
|
8
|
+
|
9
|
+
# Subtitle
|
10
|
+
attr_accessor :subtitle
|
11
|
+
|
12
|
+
# Author site
|
13
|
+
attr_accessor :author
|
14
|
+
|
15
|
+
# Email to contact author
|
16
|
+
attr_accessor :email
|
17
|
+
|
18
|
+
# Domain for host site
|
19
|
+
attr_accessor :domain
|
20
|
+
|
21
|
+
# Remote directory for site
|
22
|
+
attr_accessor :directory
|
23
|
+
|
24
|
+
# Theme directory name.
|
25
|
+
attr_accessor :theme
|
26
|
+
|
27
|
+
# Finder for posts
|
28
|
+
attr_accessor :find
|
29
|
+
|
30
|
+
# Finder for archived posts
|
31
|
+
attr_accessor :find_archived
|
32
|
+
|
33
|
+
# Finder for drafted posts
|
34
|
+
attr_accessor :find_drafted
|
35
|
+
|
36
|
+
def initialize(attributes = {})
|
37
|
+
attributes.instance_variables_set_to(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_all_tags
|
41
|
+
(find.all_tags + find_archived.all_tags).uniq.sort
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_tag(tag)
|
45
|
+
find.tag(tag) || find_archived.tag(tag)
|
46
|
+
end
|
47
|
+
|
48
|
+
end # class Site
|
49
|
+
|
50
|
+
end #module Postview
|
51
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Postview
|
2
|
+
|
3
|
+
# Copyright (c) 2009 Hallison Batista
|
4
|
+
module Version #:nodoc: all
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def info
|
9
|
+
@version ||= OpenStruct.new(YAML.load_file(File.join(ROOT, "VERSION")))
|
10
|
+
end
|
11
|
+
|
12
|
+
def tag
|
13
|
+
%w{major minor patch release}.map do |tag|
|
14
|
+
info.send(tag)
|
15
|
+
end.compact.join(".")
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{name.sub(/::.*/,'')} v#{tag} (#{info.date.strftime('%B, %d %Y')}, #{info.cycle})"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end # module Version
|
25
|
+
|
26
|
+
end # module Postview
|
27
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'hanna/rdoctask'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rdoc'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Generate RDoc API documentation."
|
9
|
+
Rake::RDocTask.new("doc:api") do |doc|
|
10
|
+
doc.title = Postview.name
|
11
|
+
doc.main = %q{README.rdoc}
|
12
|
+
doc.options = %w{--line-numbers --show-hash}
|
13
|
+
doc.rdoc_dir = %q{doc/api}
|
14
|
+
doc.rdoc_files.include %w{
|
15
|
+
HISTORY
|
16
|
+
LICENSE
|
17
|
+
README.rdoc
|
18
|
+
lib/**/*.rb
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
data/tasks/history.rake
ADDED
data/tasks/homepage.rake
ADDED
data/tasks/package.rake
ADDED
data/tasks/version.rake
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'parsedate'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
def default_version
|
5
|
+
{ :major => 0,
|
6
|
+
:minor => 1,
|
7
|
+
:patch => 0,
|
8
|
+
:release => nil,
|
9
|
+
:date => Date.today,
|
10
|
+
:timestamp => DateTime.now,
|
11
|
+
:cycle => "Development version - Pre-alpha" }
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_version(file = "VERSION")
|
15
|
+
File.exist?(file) ? YAML.load_file(file) : default_version
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_version(file = "VERSION")
|
19
|
+
@current_value ||= OpenStruct.new(load_version)
|
20
|
+
end
|
21
|
+
|
22
|
+
namespace :version do
|
23
|
+
desc "Generate version for new release and tagging."
|
24
|
+
task :new, [:major, :minor, :patch, :release, :date, :cycle, :filename] do |spec, args|
|
25
|
+
version_file = args[:filename] || "VERSION"
|
26
|
+
current = current_version(version_file)
|
27
|
+
date = Date.new(*ParseDate.parsedate(args.date || current.date.to_s).compact) unless args or current
|
28
|
+
newer = {
|
29
|
+
:major => (args[:major] || current.major).to_i,
|
30
|
+
:minor => (args[:minor] || current.minor).to_i,
|
31
|
+
:patch => (args[:patch] || current.patch).to_i,
|
32
|
+
:release => args[:release].to_s.empty? ? nil : args[:release].to_i,
|
33
|
+
:date => date || Date.today,
|
34
|
+
:timestamp => current.timestamp || default_version[:timestamp],
|
35
|
+
:cycle => args[:cycle] || current.cycle
|
36
|
+
}
|
37
|
+
|
38
|
+
newer.merge(current.marshal_dump) do |key, new_value, current_value|
|
39
|
+
new_value || current_value
|
40
|
+
end
|
41
|
+
|
42
|
+
File.open(version_file, "w+") do |version|
|
43
|
+
version << newer.to_yaml
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Show the current version."
|
48
|
+
task :show do
|
49
|
+
version = [:major, :minor, :patch, :release].map do |info|
|
50
|
+
current_version.send info
|
51
|
+
end.compact.join('.')
|
52
|
+
$stdout.puts "Version #{version} released at #{current_version.date} (#{current_version.cycle})"
|
53
|
+
@version = current_version
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|