jekyll-webmention_io 2.8.5 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/jekyll/assets/JekyllWebmentionIO.js +32 -15
- data/lib/jekyll/assets/_utils.js +1 -0
- data/lib/jekyll/assets/webmention_counters.js +2 -1
- data/lib/jekyll/assets/webmention_loader.js +1 -0
- data/lib/jekyll/commands/webmention.rb +14 -13
- data/lib/jekyll/generators/compile_js.rb +47 -24
- data/lib/jekyll/generators/gather_webmentions.rb +100 -215
- data/lib/jekyll/generators/queue_webmentions.rb +34 -31
- data/lib/jekyll/tags/_.rb +60 -56
- data/lib/jekyll/tags/bookmarks.rb +29 -0
- data/lib/jekyll/tags/count.rb +5 -3
- data/lib/jekyll/tags/likes.rb +4 -2
- data/lib/jekyll/tags/links.rb +4 -2
- data/lib/jekyll/tags/posts.rb +6 -4
- data/lib/jekyll/tags/replies.rb +4 -2
- data/lib/jekyll/tags/reposts.rb +4 -2
- data/lib/jekyll/tags/rsvps.rb +29 -0
- data/lib/jekyll/tags/webmentions.rb +5 -3
- data/lib/jekyll/tags/webmentions_head.rb +2 -0
- data/lib/jekyll/tags/webmentions_js.rb +3 -0
- data/lib/jekyll/templates/bookmarks.html +26 -0
- data/lib/jekyll/templates/links.html +1 -1
- data/lib/jekyll/templates/posts.html +1 -1
- data/lib/jekyll/templates/replies.html +1 -1
- data/lib/jekyll/templates/rsvps.html +19 -0
- data/lib/jekyll/webmention_io/version.rb +3 -1
- data/lib/jekyll/webmention_io/webmention.rb +178 -0
- data/lib/jekyll/webmention_io.rb +134 -70
- data/lib/jekyll-webmention_io.rb +2 -0
- metadata +7 -2
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
# (c) Aaron Gustafson
|
4
|
+
# https://github.com/aarongustafson/jekyll-webmention_io
|
5
|
+
# Licence : MIT
|
6
|
+
#
|
7
|
+
# this liquid plugin insert a webmentions into your Octopress or Jekill blog
|
8
|
+
# using http://webmention.io/ and the following syntax:
|
9
|
+
#
|
10
|
+
# {% webmention_rsvps post.url %}
|
11
|
+
#
|
12
|
+
module Jekyll
|
13
|
+
module WebmentionIO
|
14
|
+
class WebmentionRsvpsTag < Jekyll::WebmentionIO::WebmentionTag
|
15
|
+
def initialize(tag_name, text, tokens)
|
16
|
+
super
|
17
|
+
@text = text
|
18
|
+
self.template = "rsvps"
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_data(data, _types)
|
22
|
+
webmentions = extract_type "rsvps", data
|
23
|
+
@data = { "webmentions" => webmentions.values }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Liquid::Template.register_tag("webmention_rsvps", Jekyll::WebmentionIO::WebmentionRsvpsTag)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
1
3
|
# (c) Aaron Gustafson
|
2
4
|
# https://github.com/aarongustafson/jekyll-webmention_io
|
3
5
|
# Licence : MIT
|
@@ -5,15 +7,15 @@
|
|
5
7
|
# this liquid plugin insert a webmentions into your Octopress or Jekill blog
|
6
8
|
# using http://webmention.io/ and the following syntax:
|
7
9
|
#
|
8
|
-
# {% webmentions post.url [ likes | links | posts | replies | reposts ]* %}
|
10
|
+
# {% webmentions post.url [ bookmarks | likes | links | posts | replies | reposts | rsvps ]* %}
|
9
11
|
#
|
10
12
|
module Jekyll
|
11
13
|
module WebmentionIO
|
12
14
|
class WebmentionsTag < Jekyll::WebmentionIO::WebmentionTag
|
13
|
-
def initialize(
|
15
|
+
def initialize(tag_name, text, tokens)
|
14
16
|
super
|
15
17
|
@text = text
|
16
|
-
|
18
|
+
self.template = "webmentions"
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
1
3
|
# (c) Aaron Gustafson
|
2
4
|
# https://github.com/aarongustafson/jekyll-webmention_io
|
3
5
|
# Licence : MIT
|
@@ -31,6 +33,7 @@ module Jekyll
|
|
31
33
|
js << "<script src=\"#{js_file_path}\" async></script>"
|
32
34
|
end
|
33
35
|
|
36
|
+
Jekyll::WebmentionIO.log "info", "Gathering templates for JavaScript."
|
34
37
|
templates = ""
|
35
38
|
template_files = Jekyll::WebmentionIO.types + %w(count webmentions)
|
36
39
|
template_files.each do |template|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<div class="webmentions webmentions--bookmarks">
|
2
|
+
{% if webmentions.size > 0 %}
|
3
|
+
<ol class="webmentions__list">
|
4
|
+
{% for webmention in webmentions %}
|
5
|
+
<li id="webmention-{{ webmention.id }}" class="webmentions__item webmention webmention--{{ webmention.type }}">
|
6
|
+
<div class="webmention__content p-content">
|
7
|
+
{{ webmention.content }}
|
8
|
+
</div>
|
9
|
+
<div class="webmention__meta">
|
10
|
+
{% if webmention.author %}
|
11
|
+
<a class="webmention__author h-card u-url" href="{{ webmention.author.url }}">{{ webmention.author.name }}</a>
|
12
|
+
{% endif %}
|
13
|
+
{% if webmention.pubdate and webmention.url %}on{% endif %}
|
14
|
+
{% if webmention.pubdate %}
|
15
|
+
<a class="webmention__source u-url" href="{{ webmention.url }}">
|
16
|
+
<time class="webmention__pubdate dt-published" datetime="{{ webmention.pubdate | date: '%FT%T%:z' }}">{{ webmention.pubdate | date: '%d %B %Y' }}</time>
|
17
|
+
</a>
|
18
|
+
{% endif %}
|
19
|
+
</div>
|
20
|
+
</li>
|
21
|
+
{% endfor %}
|
22
|
+
</ol>
|
23
|
+
{% else %}
|
24
|
+
<p class="webmentions__not-found">No bookmarks were found.</p>
|
25
|
+
{% endif %}
|
26
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="webmentions webmentions--rsvps">
|
2
|
+
{% if webmentions.size > 0 %}
|
3
|
+
<ol class="webmentions__list">
|
4
|
+
{% for webmention in webmentions %}
|
5
|
+
<li id="webmention-{{ webmention.id }}" class="webmentions__item webmention webmention--{{ webmention.type }}">
|
6
|
+
<div class="webmention__author p-author h-card">
|
7
|
+
<a class="u-url" href="{{ webmention.author.url }}">
|
8
|
+
<img class="webmention__author__photo u-photo" src="{{ webmention.author.photo }}" alt="Avatar for {{ webmention.author.name }}" title="{{ webmention.author.name }}">
|
9
|
+
<b class="p-name">{{ webmention.author.name }}</b>
|
10
|
+
{{ webmention.content }}
|
11
|
+
</a>
|
12
|
+
</div>
|
13
|
+
</li>
|
14
|
+
{% endfor %}
|
15
|
+
</ol>
|
16
|
+
{% else %}
|
17
|
+
<p class="webmentions__not-found">No RSVPs were found.</p>
|
18
|
+
{% endif %}
|
19
|
+
</div>
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
# (c) Aaron Gustafson
|
4
|
+
# https://github.com/aarongustafson/jekyll-webmention_io
|
5
|
+
# Licence : MIT
|
6
|
+
#
|
7
|
+
# this liquid plugin insert a webmentions into your Octopress or Jekill blog
|
8
|
+
# using http://webmention.io/ and the following syntax:
|
9
|
+
#
|
10
|
+
module Jekyll
|
11
|
+
module WebmentionIO
|
12
|
+
class Webmention
|
13
|
+
attr_reader :id, :hash
|
14
|
+
|
15
|
+
def initialize(mention, site)
|
16
|
+
@raw = mention
|
17
|
+
@site = site
|
18
|
+
|
19
|
+
@uri = determine_uri
|
20
|
+
@source = determine_source
|
21
|
+
@id = determine_id
|
22
|
+
@type = determine_type
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
gather_content
|
27
|
+
|
28
|
+
the_hash = {
|
29
|
+
"id" => @id,
|
30
|
+
"uri" => @uri,
|
31
|
+
"source" => @source,
|
32
|
+
"pubdate" => @pubdate,
|
33
|
+
"raw" => @raw,
|
34
|
+
"author" => @author,
|
35
|
+
"type" => @type,
|
36
|
+
}
|
37
|
+
|
38
|
+
the_hash["title"] = @title if @title
|
39
|
+
the_hash["content"] = @content || ""
|
40
|
+
|
41
|
+
the_hash
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def gather_content
|
47
|
+
@pubdate = determine_pubdate
|
48
|
+
@author = determine_author
|
49
|
+
@title = determine_title
|
50
|
+
@content = determine_content
|
51
|
+
end
|
52
|
+
|
53
|
+
def markdownify(string)
|
54
|
+
unless @converter
|
55
|
+
@converter = if defined? @site.find_converter_instance
|
56
|
+
@site.find_converter_instance(::Jekyll::Converters::Markdown)
|
57
|
+
else
|
58
|
+
@site.getConverterImpl(::Jekyll::Converters::Markdown)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if string
|
63
|
+
string = @converter.convert(string.to_s)
|
64
|
+
unless string.start_with?("<p")
|
65
|
+
string = string.sub(/^<[^>]+>/, "<p>").sub(/<\/[^>]+>$/, "</p>")
|
66
|
+
end
|
67
|
+
string.strip
|
68
|
+
else
|
69
|
+
string
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def determine_uri
|
74
|
+
@raw["data"]["url"] || @raw["source"]
|
75
|
+
end
|
76
|
+
|
77
|
+
def determine_source
|
78
|
+
if @uri.include? "twitter.com/"
|
79
|
+
"twitter"
|
80
|
+
elsif @uri.include? "/googleplus/"
|
81
|
+
"googleplus"
|
82
|
+
else
|
83
|
+
false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def determine_id
|
88
|
+
id = @raw["id"].to_s
|
89
|
+
if @source == "twitter" && !@uri.include?("#favorited-by")
|
90
|
+
id = URI(@uri).path.split("/").last.to_s
|
91
|
+
end
|
92
|
+
unless id
|
93
|
+
time = Time.now
|
94
|
+
id = time.strftime("%s").to_s
|
95
|
+
end
|
96
|
+
id
|
97
|
+
end
|
98
|
+
|
99
|
+
def determine_type
|
100
|
+
type = @raw.dig("activity", "type")
|
101
|
+
unless type
|
102
|
+
type = "post"
|
103
|
+
if @source == "googleplus"
|
104
|
+
type = if @uri.include? "/like/"
|
105
|
+
"like"
|
106
|
+
elsif @uri.include? "/repost/"
|
107
|
+
"repost"
|
108
|
+
elsif @uri.include? "/comment/"
|
109
|
+
"reply"
|
110
|
+
else
|
111
|
+
"link"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
type
|
116
|
+
end
|
117
|
+
|
118
|
+
def determine_pubdate
|
119
|
+
pubdate = @raw.dig("data", "published_ts")
|
120
|
+
if pubdate
|
121
|
+
pubdate = Time.at(pubdate)
|
122
|
+
elsif @raw["verified_date"]
|
123
|
+
pubdate = Time.parse(@raw["verified_date"])
|
124
|
+
end
|
125
|
+
pubdate
|
126
|
+
end
|
127
|
+
|
128
|
+
def determine_author
|
129
|
+
@raw.dig("data", "author")
|
130
|
+
end
|
131
|
+
|
132
|
+
def determine_title
|
133
|
+
title = false
|
134
|
+
|
135
|
+
if @type == "post"
|
136
|
+
|
137
|
+
html_source = Jekyll::WebmentionIO.get_uri_source(@uri)
|
138
|
+
unless html_source
|
139
|
+
return title
|
140
|
+
end
|
141
|
+
|
142
|
+
unless html_source.valid_encoding?
|
143
|
+
html_source = html_source.encode("UTF-16be", :invalid => :replace, :replace => "?").encode("UTF-8")
|
144
|
+
end
|
145
|
+
|
146
|
+
# Check the `title` first
|
147
|
+
matches = /<title>(.*)<\/title>/.match(html_source)
|
148
|
+
if matches
|
149
|
+
title = matches[1].strip
|
150
|
+
else
|
151
|
+
# Fall back to the first `h1`
|
152
|
+
matches = /<h1>(.*)<\/h1>/.match(html_source)
|
153
|
+
title = if matches
|
154
|
+
matches[1].strip
|
155
|
+
else
|
156
|
+
title = "No title available"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# cleanup
|
161
|
+
title = title.gsub(/<\/?[^>]+?>/, "")
|
162
|
+
end # if post
|
163
|
+
|
164
|
+
markdownify(title)
|
165
|
+
end
|
166
|
+
|
167
|
+
def determine_content
|
168
|
+
content = if %w(post reply link).include? @type
|
169
|
+
@raw.dig("data", "content")
|
170
|
+
else
|
171
|
+
@raw.dig("activity", "sentence_html")
|
172
|
+
end
|
173
|
+
|
174
|
+
markdownify(content)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
data/lib/jekyll/webmention_io.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
1
3
|
# (c) Aaron Gustafson
|
2
4
|
# https://github.com/aarongustafson/jekyll-webmention_io
|
3
5
|
# Licence : MIT
|
@@ -6,6 +8,7 @@
|
|
6
8
|
# using http://webmention.io/ and the following syntax:
|
7
9
|
#
|
8
10
|
require_relative "webmention_io/version"
|
11
|
+
require_relative "webmention_io/webmention"
|
9
12
|
|
10
13
|
require "json"
|
11
14
|
require "net/http"
|
@@ -23,7 +26,12 @@ module Jekyll
|
|
23
26
|
@api_endpoint = @api_url
|
24
27
|
@api_suffix = ""
|
25
28
|
|
26
|
-
@types = %w(likes links posts replies reposts)
|
29
|
+
@types = %w(bookmarks likes links posts replies reposts rsvps)
|
30
|
+
|
31
|
+
EXCEPTIONS = [ SocketError, Timeout::Error, Errno::EINVAL,
|
32
|
+
Errno::ECONNRESET, Errno::ECONNREFUSED, EOFError,
|
33
|
+
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
34
|
+
Net::ProtocolError, OpenSSL::SSL::SSLError, ].freeze
|
27
35
|
|
28
36
|
def self.bootstrap
|
29
37
|
# @jekyll_config = Jekyll.configuration({ 'quiet' => true })
|
@@ -49,7 +57,7 @@ module Jekyll
|
|
49
57
|
end
|
50
58
|
end
|
51
59
|
|
52
|
-
#
|
60
|
+
# Getters
|
53
61
|
def self.config
|
54
62
|
@config
|
55
63
|
end
|
@@ -74,6 +82,16 @@ module Jekyll
|
|
74
82
|
@types
|
75
83
|
end
|
76
84
|
|
85
|
+
# Setters
|
86
|
+
def self.api_path=(path)
|
87
|
+
@api_endpoint = "#{@api_url}/#{path}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.api_suffix=(suffix)
|
91
|
+
@api_suffix = suffix
|
92
|
+
end
|
93
|
+
|
94
|
+
# Heplers
|
77
95
|
def self.get_cache_file_path(key)
|
78
96
|
path = false
|
79
97
|
if @cache_files.key? key
|
@@ -82,24 +100,59 @@ module Jekyll
|
|
82
100
|
return path
|
83
101
|
end
|
84
102
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
# end.join('&')
|
90
|
-
# end
|
103
|
+
def self.read_cached_webmentions(which)
|
104
|
+
unless %w(incoming outgoing).include? which
|
105
|
+
return {}
|
106
|
+
end
|
91
107
|
|
92
|
-
|
93
|
-
|
108
|
+
cache_file = get_cache_file_path which
|
109
|
+
cached_webmentions = open(cache_file) { |f| YAML.load(f) }
|
110
|
+
|
111
|
+
cached_webmentions
|
94
112
|
end
|
95
113
|
|
96
|
-
def self.
|
97
|
-
|
114
|
+
def self.cache_webmentions(which, webmentions)
|
115
|
+
if %w(incoming outgoing).include? which
|
116
|
+
cache_file = get_cache_file_path which
|
117
|
+
File.open(cache_file, "w") { |f| YAML.dump(webmentions, f) }
|
118
|
+
|
119
|
+
Jekyll::WebmentionIO.log "msg", "#{which.capitalize} webmentions have been cached."
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.gather_documents(site)
|
124
|
+
documents = if Jekyll::VERSION >= "3.0.0"
|
125
|
+
site.posts.docs.clone
|
126
|
+
else
|
127
|
+
site.posts.clone
|
128
|
+
end
|
129
|
+
|
130
|
+
if @config.dig("pages") == true
|
131
|
+
Jekyll::WebmentionIO.log "info", "Including site pages."
|
132
|
+
documents.concat site.pages.clone
|
133
|
+
end
|
134
|
+
|
135
|
+
collections = @config.dig("collections")
|
136
|
+
if collections
|
137
|
+
Jekyll::WebmentionIO.log "info", "Adding collections."
|
138
|
+
site.collections.each do |name, collection|
|
139
|
+
# skip _posts
|
140
|
+
next if name == "posts"
|
141
|
+
|
142
|
+
unless collections.is_a?(Array) && !collections.include?(name)
|
143
|
+
documents.concat collection.docs.clone
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
return documents
|
98
149
|
end
|
99
150
|
|
100
151
|
def self.get_response(api_params)
|
101
152
|
api_params << @api_suffix
|
102
|
-
|
153
|
+
url = "#{@api_endpoint}?#{api_params}"
|
154
|
+
Jekyll::WebmentionIO.log "info", "Sending request to #{url}."
|
155
|
+
source = get_uri_source(url)
|
103
156
|
if source
|
104
157
|
JSON.parse(source)
|
105
158
|
else
|
@@ -145,7 +198,7 @@ module Jekyll
|
|
145
198
|
# supported: daily, weekly, monthly, yearly, every X days|weeks|months|years
|
146
199
|
def self.get_date_from_string(text)
|
147
200
|
today = Date.today
|
148
|
-
pattern =
|
201
|
+
pattern = /every\s(?:(\d+)\s)?(day|week|month|year)s?/
|
149
202
|
matches = text.match(pattern)
|
150
203
|
unless matches
|
151
204
|
text = if text == "daily"
|
@@ -167,7 +220,7 @@ module Jekyll
|
|
167
220
|
end
|
168
221
|
|
169
222
|
def self.get_webmention_endpoint(uri)
|
170
|
-
# log
|
223
|
+
# log "info", "Looking for webmention endpoint at #{uri}"
|
171
224
|
begin
|
172
225
|
endpoint = Webmention::Client.supports_webmention?(uri)
|
173
226
|
unless endpoint
|
@@ -184,8 +237,8 @@ module Jekyll
|
|
184
237
|
log "info", "Sending webmention of #{target} in #{source}"
|
185
238
|
# return `curl -s -i -d \"source=#{source}&target=#{target}\" -o /dev/null #{endpoint}`
|
186
239
|
response = Webmention::Client.send_mention(endpoint, source, target, true)
|
187
|
-
status = response.dig(
|
188
|
-
if status ==
|
240
|
+
status = response.dig("parsed_response", "data", "status").to_s
|
241
|
+
if status == "200"
|
189
242
|
log "info", "Webmention successful!"
|
190
243
|
return response.response.body
|
191
244
|
else
|
@@ -195,68 +248,25 @@ module Jekyll
|
|
195
248
|
end
|
196
249
|
|
197
250
|
def self.get_template_contents(template)
|
198
|
-
if Jekyll::WebmentionIO.config.dig("templates", template)
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
# Jekyll::WebmentionIO::log 'info', "Template file: #{template_file}"
|
251
|
+
template_file = if Jekyll::WebmentionIO.config.dig("templates", template)
|
252
|
+
Jekyll::WebmentionIO.log "info", "Using custom #{template} template"
|
253
|
+
Jekyll::WebmentionIO.config["templates"][template]
|
254
|
+
else
|
255
|
+
File.expand_path("templates/#{template}.html", __dir__)
|
256
|
+
end
|
257
|
+
Jekyll::WebmentionIO.log "info", "Template file: #{template_file}"
|
206
258
|
handler = File.open(template_file, "rb")
|
207
259
|
handler.read
|
208
260
|
end
|
209
261
|
|
210
262
|
# Connections
|
211
|
-
def self.uri_ok?(uri)
|
212
|
-
uri = URI.parse(URI.encode(uri))
|
213
|
-
now = Time.now.to_s
|
214
|
-
bad_uris = open(@cache_files["bad_uris"]) { |f| YAML.safe_load(f) }
|
215
|
-
if bad_uris.key? uri.host
|
216
|
-
last_checked = DateTime.parse(bad_uris[uri.host])
|
217
|
-
cache_bad_uris_for = @config["cache_bad_uris_for"] || 1 # in days
|
218
|
-
recheck_at = last_checked.next_day(cache_bad_uris_for).to_s
|
219
|
-
if recheck_at > now
|
220
|
-
return false
|
221
|
-
end
|
222
|
-
end
|
223
|
-
return true
|
224
|
-
end
|
225
|
-
|
226
|
-
# Cache bad URLs for a bit
|
227
|
-
def self.uri_is_not_ok(uri)
|
228
|
-
# Never cache webmention.io in here
|
229
|
-
if uri.host == 'webmention.io'
|
230
|
-
return
|
231
|
-
end
|
232
|
-
cache_file = @cache_files["bad_uris"]
|
233
|
-
bad_uris = open(cache_file) { |f| YAML.safe_load(f) }
|
234
|
-
bad_uris[uri.host] = Time.now.to_s
|
235
|
-
File.open(cache_file, "w") { |f| YAML.dump(bad_uris, f) }
|
236
|
-
end
|
237
|
-
|
238
263
|
def self.get_uri_source(uri, redirect_limit = 10, original_uri = false)
|
239
264
|
original_uri ||= uri
|
240
265
|
unless uri_ok?(uri)
|
241
266
|
return false
|
242
267
|
end
|
243
|
-
if redirect_limit
|
244
|
-
|
245
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
246
|
-
http.read_timeout = 10
|
247
|
-
if uri.scheme == "https"
|
248
|
-
http.use_ssl = true
|
249
|
-
http.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:-LOW"
|
250
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
251
|
-
end
|
252
|
-
begin
|
253
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
254
|
-
response = http.request(request)
|
255
|
-
rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, Errno::ECONNREFUSED, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, OpenSSL::SSL::SSLError => e
|
256
|
-
log "warn", "Got an error checking #{original_uri}: #{e}"
|
257
|
-
uri_is_not_ok(uri)
|
258
|
-
return false
|
259
|
-
end
|
268
|
+
if redirect_limit.positive?
|
269
|
+
response = get_http_response(uri)
|
260
270
|
case response
|
261
271
|
when Net::HTTPSuccess then
|
262
272
|
return response.body.force_encoding("UTF-8")
|
@@ -278,9 +288,63 @@ module Jekyll
|
|
278
288
|
end
|
279
289
|
|
280
290
|
def self.log(type, message)
|
281
|
-
|
291
|
+
debug = !!@config.dig("debug")
|
292
|
+
if debug || %w(error msg).include?(type)
|
293
|
+
if type == "msg"
|
294
|
+
type = "info"
|
295
|
+
end
|
296
|
+
Jekyll.logger.method(type).call("#{@logger_prefix} #{message}")
|
297
|
+
end
|
282
298
|
end
|
283
299
|
|
300
|
+
private
|
301
|
+
|
302
|
+
def self.get_http_response(uri)
|
303
|
+
uri = URI.parse(URI.encode(uri))
|
304
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
305
|
+
http.read_timeout = 10
|
306
|
+
if uri.scheme == "https"
|
307
|
+
http.use_ssl = true
|
308
|
+
http.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:-LOW"
|
309
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
310
|
+
end
|
311
|
+
begin
|
312
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
313
|
+
response = http.request(request)
|
314
|
+
return response
|
315
|
+
rescue *EXCEPTIONS => e
|
316
|
+
log "warn", "Got an error checking #{original_uri}: #{e}"
|
317
|
+
uri_is_not_ok(uri)
|
318
|
+
return false
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
# Cache bad URLs for a bit
|
323
|
+
def self.uri_is_not_ok(uri)
|
324
|
+
# Never cache webmention.io in here
|
325
|
+
if uri.host == "webmention.io"
|
326
|
+
return
|
327
|
+
end
|
328
|
+
cache_file = @cache_files["bad_uris"]
|
329
|
+
bad_uris = open(cache_file) { |f| YAML.load(f) }
|
330
|
+
bad_uris[uri.host] = Time.now.to_s
|
331
|
+
File.open(cache_file, "w") { |f| YAML.dump(bad_uris, f) }
|
332
|
+
end
|
333
|
+
|
334
|
+
def self.uri_ok?(uri)
|
335
|
+
uri = URI.parse(URI.encode(uri))
|
336
|
+
now = Time.now.to_s
|
337
|
+
bad_uris = open(@cache_files["bad_uris"]) { |f| YAML.load(f) }
|
338
|
+
if bad_uris.key? uri.host
|
339
|
+
last_checked = DateTime.parse(bad_uris[uri.host])
|
340
|
+
cache_bad_uris_for = @config["cache_bad_uris_for"] || 1 # in days
|
341
|
+
recheck_at = last_checked.next_day(cache_bad_uris_for).to_s
|
342
|
+
if recheck_at > now
|
343
|
+
return false
|
344
|
+
end
|
345
|
+
end
|
346
|
+
return true
|
347
|
+
end
|
284
348
|
end
|
285
349
|
end
|
286
350
|
|