Class: Jekyll::WebmentionIO::Webmentions

Inherits:
Object
  • Object
show all
Defined in:
lib/jekyll/webmentions.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(policy, client = NetworkClient.new, url = Config::DEFAULT_API_URL, path = 'mentions', suffix = '&perPage=9999') ⇒ Webmentions

Initializes a Webmention.io client, taking a WebmentionPolicy instance that is being used to control retry behaviour, a NetworkClient instance that is used to perform low-level network operations, and a set of parameters that specifies the endpoint URL, path, and query parameters to use.



16
17
18
19
20
21
22
# File 'lib/jekyll/webmentions.rb', line 16

def initialize(policy, client = NetworkClient.new, url = Config::DEFAULT_API_URL, path = 'mentions', suffix = '&perPage=9999')
  @policy = policy
  @client = client

  @api_endpoint = "#{url}/#{path}"
  @api_suffix = suffix
end

Instance Attribute Details

#api_suffix=(value) ⇒ Object (writeonly)

Sets the attribute api_suffix

Parameters:

  • value

    the value to set the attribute api_suffix to.



9
10
11
# File 'lib/jekyll/webmentions.rb', line 9

def api_suffix=(value)
  @api_suffix = value
end

Instance Method Details

#get_body_from_uri(uri, redirect_limit = 10) ⇒ Object

High-level wrapper method for making an HTTP GET call that respects redirects.

Critically, this method also updates the supplied WebmentionPolicy depending on whether the call succeeds or fails.



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/jekyll/webmentions.rb', line 103

def get_body_from_uri(uri, redirect_limit = 10)
  return false unless @policy.uri_ok?(uri)

  response = @client.http_get(uri, redirect_limit)

  if response.nil?
    @policy.failure(uri)

    false
  else
    response
  end
end

#get_webmentions(targets, since_id) ⇒ Object

Reaches out to the webmention.io API to retrieve any new webmentions for the supplied set of target URIs, each of which is expected to be aliases or equivalent URLs for the same resource (e.g. legacy URLs, redirected URLs, etc).

The API returns JSON response containing, among other things, a ‘links` key that’s mapped to an array of originating source URLs for any webmentions sent to the target.

The method returns a list of WebmentionItem instances for each of the supplied URLs.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/jekyll/webmentions.rb', line 80

def get_webmentions(targets, since_id)
  api_params = targets.collect { |v| "target[]=#{v}" }.join('&')
  api_params << "&since_id=#{since_id}" if since_id
  api_params << '&sort-by=published'

  response = get_webmention_io_response(api_params)

  links = response['links'] || []

  if links.empty?
    WebmentionIO.log 'info', 'No webmentions found.'
  else
    WebmentionIO.log 'info', "Here’s what we got back:\n\n#{response.inspect}\n\n"
  end

  links.reverse.map { |wm| WebmentionIO::WebmentionItem.new(wm) }
end

#send_webmention(source, target) ⇒ Object

Sends a webmention from the source URI to the specified target URI. Wraps up the logic for looking up the webmention endpoint, sending the webmention, and parsing the response.

Depending on the success or failure of the request, also updates the supplied retry policy to reflect the state of the webmention target endpoint.



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
# File 'lib/jekyll/webmentions.rb', line 31

def send_webmention(source, target)
  return nil if !webmention_endpoint?(URI::Parser.new.escape(target))

  Jekyll::WebmentionIO.log 'info', "Sending webmention of #{target} in #{source}"
  # return `curl -s -i -d \"source=#{source}&target=#{target}\" -o /dev/null #{endpoint}`
  response = @client.send_webmention(source, target)

  # A Webmention::ErrorResponse (connection failure, no endpoint found,
  # etc.) carries no HTTP code or body -- only a message -- so guard the
  # accessors that only a Webmention::Response provides.
  status = response.code if response.respond_to?(:code)

  case status
  when 200, 201, 202
    Jekyll::WebmentionIO.log 'info', 'Webmention successful!'
    @policy.success(target)
    response.body
  else
    Jekyll::WebmentionIO.log 'info', response.inspect
    Jekyll::WebmentionIO.log 'info', 'Webmention failed, but will remain queued for next time'

    if response.respond_to?(:body) && response.body
      begin
        body = JSON.parse(response.body)

        if body.key? 'error'
          Jekyll::WebmentionIO.log 'msg', "Endpoint returned error: #{body['error']}"
        end
      rescue StandardError => e
        WebmentionIO.log 'error', e.message
      end
    end

    @policy.error(target)
    false
  end
end