diff --git a/server/harp_blog.rb b/server/harp_blog.rb index 43c3f94..89740e8 100644 --- a/server/harp_blog.rb +++ b/server/harp_blog.rb @@ -8,6 +8,8 @@ class HarpBlog class HarpBlogError < RuntimeError ; end class InvalidDataError < HarpBlogError ; end class PostExistsError < HarpBlogError ; end + class PostAlreadyPublishedError < HarpBlogError ; end + class PostNotPublishedError < HarpBlogError ; end class PostSaveError < HarpBlogError attr_reader :original_error @@ -63,10 +65,24 @@ class HarpBlog @time ||= @timestamp ? Time.at(@timestamp) : Time.now end + def time=(time) + @timestamp = nil + @date = nil + @url = nil + @time = time + end + def timestamp @timestamp ||= time.to_i end + def timestamp=(timestamp) + @time = nil + @date = nil + @url = nil + @timestamp = timestamp + end + def url @url ||= if draft? @@ -221,6 +237,26 @@ class HarpBlog delete_post_from_dir('drafts', slug) end + def publish_post(post) + if post.draft? + new_post = create_post(post.title, post.body, post.link) + delete_post_from_dir('drafts', post.slug) + new_post + else + raise PostAlreadyPublishedError.new("post is already published: #{post.dir}/#{post.slug}") + end + end + + def unpublish_post(post) + if post.draft? + raise PostNotPublishedError.new("post is not published: #{post.dir}/#{post.slug}") + else + new_post = create_post(post.title, post.body, post.link, draft: true) + delete_post_from_dir(post.dir, post.slug) + new_post + end + end + def publish(production = false) target = production ? 'publish' : 'publish_beta' run("make #{target}") diff --git a/server/server.rb b/server/server.rb index 7bf9ec8..0679178 100755 --- a/server/server.rb +++ b/server/server.rb @@ -282,7 +282,43 @@ delete '/drafts/:slug' do |slug| status 204 end -# publish +# publish a post +post '/drafts/:slug/publish' do |slug| + unless authenticated?(request['Auth']) + status 403 + return 'forbidden' + end + + if post = blog.get_draft(slug) + new_post = blog.publish_post(post) + status 201 + headers 'Location' => url_for(new_post.url), 'Content-Type' => 'application/json' + JSON.generate(post: new_post.fields) + else + status 404 + 'not found' + end +end + +# unpublish a post +post '/posts/:year/:month/:slug/unpublish' do |year, month, slug| + unless authenticated?(request['Auth']) + status 403 + return 'forbidden' + end + + if post = blog.get_post(year, month, slug) + new_post = blog.unpublish_post(post) + status 201 + headers 'Location' => url_for(new_post.url), 'Content-Type' => 'application/json' + JSON.generate(post: new_post.fields) + else + status 404 + 'not found' + end +end + +# publish the site post '/publish' do unless authenticated?(request['Auth']) status 403 diff --git a/server/spec/harp_blog_spec.rb b/server/spec/harp_blog_spec.rb index 02deb22..9650b24 100644 --- a/server/spec/harp_blog_spec.rb +++ b/server/spec/harp_blog_spec.rb @@ -459,4 +459,56 @@ RSpec.describe HarpBlog do end end + describe '#publish_post' do + it "should publish drafts" do + title = 'a-shiny-new-post' + body = 'blah blah blah' + link = 'http://samhuri.net' + post = @blog.create_post(title, body, link, draft: true) + new_post = @blog.publish_post(post) + expect(new_post).to be_truthy + expect(new_post.draft?).to be_falsy + expect(new_post.title).to eq(title) + expect(new_post.body).to eq(body) + expect(new_post.link).to eq(link) + + draft = @blog.get_draft(post.slug) + expect(draft).to eq(nil) + + post = @blog.get_post(post.time.year.to_s, post.padded_month, post.slug) + expect(post).to be_truthy + end + + it "should raise an error for published posts" do + post = @blog.get_post('2006', '02', 'first-post') + expect { @blog.publish_post(post) }.to raise_error + end + end + + describe '#unpublish_post' do + it "should unpublish posts" do + post = @blog.get_post('2006', '02', 'first-post') + new_post = @blog.unpublish_post(post) + expect(new_post).to be_truthy + expect(new_post.draft?).to be_truthy + expect(new_post.title).to eq(post.title) + expect(new_post.body).to eq(post.body) + expect(new_post.link).to eq(post.link) + + post = @blog.get_post(post.time.year.to_s, post.padded_month, post.slug) + expect(post).to eq(nil) + + draft = @blog.get_draft(new_post.slug) + expect(draft).to be_truthy + end + + it "should raise an error for drafts" do + title = 'a-shiny-new-post' + body = 'blah blah blah' + link = 'http://samhuri.net' + post = @blog.create_post(title, body, link, draft: true) + expect { @blog.unpublish_post(post) }.to raise_error + end + end + end