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