lib/shinmun/blog.rb in georgi-shinmun-0.4.1 vs lib/shinmun/blog.rb in georgi-shinmun-0.5
- old
+ new
@@ -1,106 +1,78 @@
module Shinmun
+ ROOT = File.expand_path(File.dirname(__FILE__) + '/../..')
class Blog < Kontrol::Application
-
- EXAMPLE_DIR = File.expand_path(File.dirname(__FILE__) + '/../../example')
-
include Helpers
- attr_reader :aggregations, :categories, :comments, :repo, :store
+ attr_accessor :config, :store, :posts, :pages
- %w[ assets comments config posts pages templates ].each do |name|
- define_method(name) { store.root.tree(name) }
+ %w[ base_path title description language author categories ].each do |name|
+ define_method(name) { @config[name.to_sym] }
end
- %w[ title description language author url base_path categories ].each do |name|
- define_method(name) { config['blog.yml'][name] }
- end
-
# Initialize the blog
def initialize(path)
super
- @aggregations = {}
-
- if ENV['RACK_ENV'] == 'production'
- @store = GitStore.new(path)
- else
- @store = GitStore::FileStore.new(path)
- end
-
- @store.load
-
- @repo = Grit::Repo.new(path) if defined?(Grit)
-
- Thread.start do
- loop do
- load_aggregations
- sleep 300
- end
- end
+ @config = {}
+ @store = GitStore.new(path)
+ @store.handler['md'] = PostHandler.new
+ @store.handler['rhtml'] = ERBHandler.new
+ @store.handler['rxml'] = ERBHandler.new
end
- def self.init(name)
- Dir.mkdir name
- Dir.chdir name
- FileUtils.cp_r EXAMPLE_DIR + '/.', '.'
- `git init`
- `git add .`
- `git commit -m 'init'`
- end
+ def self.init(path)
+ path = File.expand_path(path)
+ Dir.mkdir(path)
- def load_template(file)
- templates[file] or raise "template #{file} not found"
- end
+ FileUtils.cp_r "#{ROOT}/assets", path
+ FileUtils.cp_r "#{ROOT}/templates", path
+ FileUtils.cp "#{ROOT}/config.ru", path
- def render(name, vars = {})
- super(name, vars.merge(:blog => self))
- end
+ Dir.mkdir("#{path}/posts")
+ Dir.mkdir("#{path}/pages")
+ Dir.mkdir("#{path}/comments")
+ Dir.mkdir("#{path}/public")
- def call(env)
- store.refresh!
- super
- end
+ FileUtils.ln_s("../assets", "#{path}/public/assets")
- def load_aggregations
- config['aggregations.yml'].to_a.each do |c|
- aggregations[c['name']] = Object.const_get(c['class']).new(c['url'])
+ Dir.chdir(path) do
+ `git init`
+ `git add .`
+ `git commit -m 'init'`
end
end
- def posts_by_date
- posts.sort_by { |post| post.date.to_s }.reverse
+ def load_template(file)
+ store['templates/' + file]
end
- def recent_posts
- posts_by_date[0, 20]
+ def render(name, vars = {})
+ super(name, vars.merge(:blog => self))
end
- # Return all posts for a given month.
- def posts_for_month(year, month)
- posts_by_date.select { |p| p.year == year and p.month == month }
+ def pages
+ store.tree('pages').values
end
- # Return all posts with any of given tags.
- def posts_with_tags(tags)
- return [] if tags.nil? or tags.empty?
- tags = tags.split(',').map { |t| t.strip } if tags.is_a?(String)
- posts.select do |post|
- tags.any? do |tag|
- post.tag_list.include?(tag)
- end
- end
+ def posts
+ store.tree('posts').values.sort_by { |post| post.date.to_s }.reverse
end
- # Return all archives as tuples of [year, month].
- def archives
- posts.map { |p| [p.year, p.month] }.uniq.sort
+ def call(env)
+ if ENV['RACK_ENV'] == 'production'
+ store.load if store.changed?
+ else
+ store.load(true)
+ end
+
+ super
end
- def tree(post)
- post.date ? posts.tree(post.year).tree(post.month) : pages
+ def url
+ "http://#{request.host}"
end
def symbolize_keys(hash)
hash.inject({}) do |h, (k, v)|
h[k.to_sym] = v
@@ -110,62 +82,100 @@
def transaction(message, &block)
store.transaction(message, &block)
end
- # Create a new post with given attributes.
- def create_post(atts)
- post = Post.new(atts)
- transaction "create '#{post.title}'" do
- store[post.path] = post
- end
+ def post_file(post)
+ 'posts' + post_path(post) + '.' + post.type
end
- def update_post(post, data)
- transaction "update '#{post.title}'" do
- store.delete(post.path)
- post.parse data
- store[post.path] = post
+ def page_file(post)
+ 'pages' + page_path(post) + '.' + post.type
+ end
+
+ def comment_file(post)
+ 'comments/' + post_path(post) + '.yml'
+ end
+
+ def create_post(attr)
+ post = Post.new(attr)
+ path = post_file(post)
+
+ transaction "create post `#{post.title}'" do
+ store[path] = post
end
+
+ post
end
- def delete_post(post)
- transaction "delete '#{post.title}'" do
- store.delete(post.path)
+ def create_page(attr)
+ post = Post.new(attr)
+ path = page_file(post)
+
+ transaction "create page `#{post.title}'" do
+ store[path] = post
end
+
+ post
end
- def comments_for(path)
- comments[path + '.yml'] || []
+ def comments_for(post)
+ store[comment_file post] || []
end
- def post_comment(path, params)
- transaction "new comment for '#{path}'" do
- comments[path + '.yml'] = comments[path + '.yml'].to_a + [ Comment.new(params) ]
+ def create_comment(post, params)
+ path = comment_file(post)
+ comments = comments_for(post)
+ comment = Comment.new(params)
+
+ transaction "new comment for `#{post.title}'" do
+ store[path] = comments + [comment]
end
+
+ comment
end
def find_page(name)
pages.find { |p| p.name == name }
end
def find_post(year, month, name)
- tree = posts[year, month] and tree.find { |p| p.name == name }
+ posts.find { |p| p.year == year and p.month == month and p.name == name }
end
def find_category(permalink)
- name = categories.find { |name| urlify(name) == permalink } or raise "category not found"
- posts = self.posts.select { |p| p.category == name }.sort_by { |p| p.date }.reverse
- { :name => name, :posts => posts, :permalink => permalink }
+ name = categories.find { |name| urlify(name) == permalink }
+
+ { :name => name,
+ :posts => posts.select { |p| p.category == name },
+ :permalink => permalink }
end
- def write(file, template, vars={})
- file = "public/#{base_path}/#{file}"
- FileUtils.mkdir_p(File.dirname(file))
- open(file, 'wb') do |io|
- io << render(template, vars)
+ def recent_posts
+ posts[0, 20]
+ end
+
+ # Return all posts for a given month.
+ def posts_for_month(year, month)
+ posts.select { |p| p.year == year and p.month == month }
+ end
+
+ # Return all posts with any of given tags.
+ def posts_with_tags(tags)
+ return [] if tags.nil? or tags.empty?
+ tags = tags.split(',').map { |t| t.strip } if tags.is_a?(String)
+
+ posts.select do |post|
+ tags.any? do |tag|
+ post.tag_list.include?(tag)
+ end
end
end
-
- end
+
+ # Return all archives as tuples of [year, month].
+ def archives
+ posts.map { |p| [p.year, p.month] }.uniq.sort
+ end
+
+ end
end