about summary refs log tree commit diff stats
path: root/app/controllers/blogs_controller.rb
blob: 4bbbc28d69bbd9ef09948004e763cc775f1a899b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
require 'microformats'
require 'redcarpet/render_strip'
require 'webmention'

class BlogsController < ApplicationController
  skip_before_action :verify_authenticity_token, only: [:webmention]

  def summary
    @blogs = Blog.where(published: true).order(published_at: :desc).paginate(page: params[:page], per_page: 10)
    if not params[:page]
      @main_page = true
    end
  end

  def index
    @blogs = Blog.where(published: true).order(published_at: :desc)

    respond_to do |format|
      format.html
      format.atom
    end
  end

  def show
    @blog = Blog.find_by_slug(params[:slug])

    raise ActiveRecord::RecordNotFound unless @blog
    raise ActiveRecord::RecordNotFound unless @blog.published

    @prev = @blog.prev
    @next = @blog.next

    body = Redcarpet::Markdown.new(Redcarpet::Render::StripDown).render(@blog.body)

    set_meta_tags(og: {
      title: @blog.title,
      type: "article",
      description: (body.length <= 300 ? body : body[0..299]),
      url: blog_url(@blog, host: "www.fourisland.com"),
      article: {
        published_time: @blog.published_at.iso8601,
        modified_time: @blog.updated_at.iso8601
      }
    })
  end

  def upvote
    @blog = Blog.find_by_slug(params[:slug])

    raise ActiveRecord::RecordNotFound unless @blog
    raise ActiveRecord::RecordNotFound unless @blog.published

    respond_to do |format|
      if @blog.upvote! request.remote_ip
        format.html do
          flash[:notice] = "You have upvoted the blog post \"#{@blog.title}\"."
          redirect_to @blog
        end
        format.js { render "voted" }
        format.xml { head :ok }
      else
        format.html do
          flash[:notice] = "You have already voted on the blog post \"#{@blog.title}\"."
          redirect_to @blog
        end
        format.xml { render :xml => { :error => "Someone from your IP address has already voted on this blog post."} }
      end
    end
  end

  def downvote
    @blog = Blog.find_by_slug(params[:slug])

    raise ActiveRecord::RecordNotFound unless @blog
    raise ActiveRecord::RecordNotFound unless @blog.published

    respond_to do |format|
      if @blog.downvote! request.remote_ip
        format.html do
          flash[:notice] = "You have downvoted the blog post \"#{@blog.title}\"."
          redirect_to @blog
        end
        format.js { render "voted" }
        format.xml { head :ok }
      else
        format.html do
          flash[:notice] = "You have already voted on the blog post \"#{@blog.title}\"."
          redirect_to @blog
        end
        format.xml { render :xml => { :error => "Someone from your IP address has already voted on this blog post."} }
      end
    end
  end

  def webmention
    @blog = Blog.find_by_slug(params[:slug])

    raise ActiveRecord::RecordNotFound unless @blog
    raise ActiveRecord::RecordNotFound unless @blog.published

    permalink = url_for(@blog)

    target = params[:target]
    unless target == permalink
      render json: { error: "Incorrect target for webmention endpoint (#{target} != #{permalink})." }
      return
    end

    source = params[:source]
    verification = Webmention.verify_webmention(source, target)
    unless verification.verified?
      render json: { error: "Webmention could not be verified." }
      return
    end

    response = Webmention::Request.get(source)
    parsed = Microformats.parse(response.body.to_s)

    if parsed.entry.properties.to_hash.include?("like-of") and parsed.entry.like_of(:all).map(&:to_s).include? permalink
      @blog.like!(parsed.entry.author.url, parsed.entry.author.name)
    end

    head :ok
  end

end