ficon 0.0.6 → 0.1
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 +5 -5
- data/README.md +14 -3
- data/bin/ficon +1 -2
- data/ficon.gemspec +9 -8
- data/lib/ficon/cache.rb +17 -32
- data/lib/ficon/image.rb +13 -10
- data/lib/ficon/version.rb +2 -2
- data/lib/ficon.rb +127 -92
- data/test/ficon_test.rb +11 -4
- metadata +21 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f38f205039b510b47be5f9a226ebc8680dbd2c97a38cae867c597e02ce6805b4
|
4
|
+
data.tar.gz: edefb06cd24a6091df0e92fe7ac68974cc649e0b4e3b22e73243bbcfe352a838
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d04d8330715b5194af238accadb7ab5513f3a27423ab9feb5634c03b6e5d847841eb29d4ceb85cc71faf6526b16aeaf80c561293f97b76e483789329fe5236f
|
7
|
+
data.tar.gz: 818b27e4318f1c587ed29a9925b66f846644d2cd82378cf1400b1b2e9a9298fc7f091b1981abdbbe51dd598f7b0475b3cef1e1e941ce80b7c14da65a9738bc83
|
data/README.md
CHANGED
@@ -18,10 +18,21 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
irb(main)> Ficon.
|
22
|
-
=>
|
21
|
+
irb(main)> Ficon.new('https://booko.info/9780748109999').site_icons.first.url
|
22
|
+
=> "https://booko.info/favicon-196x196.png"
|
23
23
|
|
24
|
-
|
24
|
+
irb(main)> Ficon.new('https://booko.info/9780748109999').page_images.first.url
|
25
|
+
=> "https://covers.booko.com.au/9780748109999.jpg"
|
26
|
+
|
27
|
+
irb(main)> site = Ficon.new('https://booko.info/9780748109999')
|
28
|
+
irb(main)> site.title
|
29
|
+
=> "Prices for Consider Phlebas by Iain M. Banks"
|
30
|
+
irb(main)> site.description
|
31
|
+
=> "Prices (including delivery) for Consider Phlebas by Iain M. Banks range from $12.40 at Blackwell's up to $12.99."
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
Or from the shell:
|
25
36
|
|
26
37
|
$ ficon https://booko.info/9780748109999
|
27
38
|
Site icon: https://booko.info/favicon-196x196.png([196, 196])
|
data/bin/ficon
CHANGED
data/ficon.gemspec
CHANGED
@@ -12,19 +12,20 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = %q{Ficon finds icons for websites and optionally, the best icon}
|
13
13
|
spec.homepage = "https://github.com/dkam/ficon"
|
14
14
|
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 3.0"
|
15
16
|
|
16
17
|
spec.files = `git ls-files -z`.split("\x0")
|
17
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
20
|
spec.require_paths = ["lib"]
|
20
21
|
|
21
|
-
spec.add_runtime_dependency 'nokogiri', "~> 1.
|
22
|
-
spec.add_runtime_dependency 'addressable', "~> 2"
|
23
|
-
spec.add_runtime_dependency 'fastimage', "~> 2"
|
24
|
-
spec.add_runtime_dependency 'sqlite3', "~>
|
22
|
+
spec.add_runtime_dependency 'nokogiri', "~> 1.15"
|
23
|
+
spec.add_runtime_dependency 'addressable', "~> 2.8"
|
24
|
+
spec.add_runtime_dependency 'fastimage', "~> 2.3"
|
25
|
+
spec.add_runtime_dependency 'sqlite3', "~> 2.0"
|
25
26
|
|
26
|
-
spec.add_development_dependency "bundler", "~>
|
27
|
-
spec.add_development_dependency "rake", "~>
|
28
|
-
spec.add_development_dependency "minitest", "~> 5"
|
29
|
-
spec.add_development_dependency "
|
27
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
28
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
29
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
30
|
+
spec.add_development_dependency "debug", "~> 1.0"
|
30
31
|
end
|
data/lib/ficon/cache.rb
CHANGED
@@ -1,61 +1,50 @@
|
|
1
|
-
require
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module Ficon
|
1
|
+
require "sqlite3"
|
5
2
|
|
3
|
+
class Ficon
|
6
4
|
class Cache
|
7
5
|
def initialize(url)
|
8
6
|
@url = url.to_s
|
9
|
-
Cache.setup_cache(db) if db.execute(
|
7
|
+
Cache.setup_cache(db) if db.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='urls'").length == 0
|
10
8
|
end
|
11
9
|
|
12
10
|
def db
|
13
11
|
_db = SQLite3::Database.new Cache.db_file
|
14
|
-
_db.busy_timeout=1000
|
15
|
-
|
12
|
+
_db.busy_timeout = 1000
|
13
|
+
_db
|
16
14
|
end
|
17
15
|
|
18
16
|
def data
|
19
|
-
|
20
|
-
rescue
|
21
|
-
return nil
|
17
|
+
db.execute("select data from urls where url=? limit 1", @url).first&.first
|
22
18
|
end
|
23
19
|
|
24
20
|
def data=(_value)
|
25
|
-
|
26
|
-
db.execute("
|
27
|
-
db.execute("UPDATE urls SET data=? WHERE url=?", [value, @url])
|
21
|
+
db.execute("INSERT OR IGNORE INTO urls (url, data) VALUES (?, ?)", [@url, _value])
|
22
|
+
db.execute("UPDATE urls SET data=? WHERE url=?", [_value, @url])
|
28
23
|
end
|
29
24
|
|
30
25
|
def etag
|
31
|
-
|
32
|
-
rescue
|
33
|
-
return nil
|
26
|
+
db.execute("select etag from urls where url=? limit 1", @url).first&.first
|
34
27
|
end
|
35
28
|
|
36
29
|
def etag=(_value)
|
37
|
-
|
38
|
-
db.execute("
|
39
|
-
db.execute("UPDATE urls SET etag=? WHERE url=?", [value, @url])
|
30
|
+
db.execute("INSERT OR IGNORE INTO urls (url, etag) VALUES (?, ?)", [@url, _value])
|
31
|
+
db.execute("UPDATE urls SET etag=? WHERE url=?", [_value, @url])
|
40
32
|
end
|
41
33
|
|
42
34
|
def not_before
|
43
|
-
|
44
|
-
rescue
|
45
|
-
return nil
|
35
|
+
db.execute("select not_before from urls where url=? limit 1", @url).first&.first
|
46
36
|
end
|
47
37
|
|
48
38
|
def not_before=(_value)
|
49
|
-
|
50
|
-
db.execute("
|
51
|
-
db.execute("UPDATE urls SET not_before=? WHERE url=?", [value, @url])
|
39
|
+
db.execute("INSERT OR IGNORE INTO urls (url, not_before) VALUES (?, ?)", [@url, _value])
|
40
|
+
db.execute("UPDATE urls SET not_before=? WHERE url=?", [_value, @url])
|
52
41
|
end
|
53
42
|
|
54
43
|
def self.db_file
|
55
|
-
if ENV[
|
56
|
-
File.expand_path(
|
44
|
+
if ENV["FICON_DB"].nil?
|
45
|
+
File.expand_path("~/.ficon.db")
|
57
46
|
else
|
58
|
-
ENV[
|
47
|
+
ENV["FICON_DB"]
|
59
48
|
end
|
60
49
|
end
|
61
50
|
|
@@ -63,9 +52,5 @@ module Ficon
|
|
63
52
|
db.execute("CREATE TABLE urls(url, etag, not_before, data)")
|
64
53
|
db.execute("CREATE UNIQUE INDEX `url` ON `urls` (`url`)")
|
65
54
|
end
|
66
|
-
|
67
55
|
end
|
68
56
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
data/lib/ficon/image.rb
CHANGED
@@ -1,21 +1,24 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "net/http"
|
2
|
+
require "fastimage"
|
3
|
+
require "json"
|
3
4
|
|
4
|
-
|
5
|
+
class Ficon
|
5
6
|
class Image
|
6
|
-
|
7
|
-
|
8
|
-
attr_reader :url, :size, :area
|
9
|
-
def initialize(url)
|
7
|
+
attr_reader :url, :size, :area, :tile_color
|
8
|
+
def initialize(url, tile_color = nil)
|
10
9
|
@url = url
|
10
|
+
@tile_color = tile_color
|
11
11
|
c = Cache.new(@url)
|
12
|
-
|
13
|
-
|
12
|
+
cached_size = Cache.new(url).data
|
13
|
+
@size = cached_size ? JSON.parse(cached_size) : FastImage.size(url)
|
14
|
+
c.data = @size.to_json if @size
|
14
15
|
@area = @size&.inject(&:*) || 0
|
15
16
|
end
|
16
17
|
|
17
18
|
def to_s
|
18
|
-
@url.to_s +
|
19
|
+
result = @url.to_s + " (#{@size})"
|
20
|
+
result += " [#{@tile_color}]" if @tile_color
|
21
|
+
result
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
data/lib/ficon/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.
|
1
|
+
class Ficon
|
2
|
+
VERSION = "0.1"
|
3
3
|
end
|
data/lib/ficon.rb
CHANGED
@@ -1,112 +1,147 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require "
|
5
|
-
require
|
6
|
-
|
7
|
-
|
8
|
-
require_relative
|
9
|
-
require_relative
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@site = OpenStruct.new
|
19
|
-
process
|
20
|
-
end
|
1
|
+
require "net/http"
|
2
|
+
require "nokogiri"
|
3
|
+
require "uri"
|
4
|
+
require "addressable/uri"
|
5
|
+
require "debug"
|
6
|
+
|
7
|
+
require_relative "ficon/version"
|
8
|
+
require_relative "ficon/image"
|
9
|
+
require_relative "ficon/cache"
|
10
|
+
|
11
|
+
class Ficon
|
12
|
+
attr_reader :site
|
13
|
+
def initialize(uri)
|
14
|
+
@uri = Addressable::URI.heuristic_parse(uri)
|
15
|
+
@site = {}
|
16
|
+
process
|
17
|
+
end
|
21
18
|
|
22
|
-
|
23
|
-
|
19
|
+
def doc
|
20
|
+
cache = Cache.new(@uri)
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
cache.etag = @data.meta['etag'] if @data.respond_to?(:meta)
|
31
|
-
cache.not_before = @data.meta['last-modified'] if @data.respond_to?(:meta)
|
32
|
-
@data.rewind
|
33
|
-
end
|
22
|
+
@data ||= cache.data
|
23
|
+
|
24
|
+
if @data.nil?
|
25
|
+
response = fetch_url(@uri)
|
26
|
+
return nil unless response
|
34
27
|
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
return nil
|
40
|
-
rescue TypeError => e
|
41
|
-
if uri.to_s =~ /^http/
|
42
|
-
puts "#{e.inspect}"
|
43
|
-
puts "#{e.backtrace.join('\n')}"
|
44
|
-
else
|
45
|
-
puts "Please prepend http:// or https:// to the URL"
|
46
|
-
end
|
47
|
-
return nil
|
48
|
-
rescue RuntimeError => e
|
49
|
-
puts "#{e.message}"
|
50
|
-
return nil
|
28
|
+
@data = response.body.force_encoding("UTF-8")
|
29
|
+
cache.data = @data
|
30
|
+
cache.etag = response["etag"] if response["etag"]
|
31
|
+
cache.not_before = response["last-modified"] if response["last-modified"]
|
51
32
|
end
|
52
33
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
34
|
+
@doc ||= Nokogiri::HTML(@data)
|
35
|
+
@doc
|
36
|
+
rescue Net::HTTPError, SocketError => e
|
37
|
+
puts "HTTP Error: #{e.inspect}"
|
38
|
+
nil
|
39
|
+
rescue TypeError => e
|
40
|
+
if /^http/.match?(@uri.to_s)
|
41
|
+
puts "#{e.inspect}"
|
42
|
+
puts "#{e.backtrace.join('\n')}"
|
43
|
+
else
|
44
|
+
puts "Please prepend http:// or https:// to the URL"
|
58
45
|
end
|
46
|
+
nil
|
47
|
+
rescue RuntimeError => e
|
48
|
+
puts "#{e.message}"
|
49
|
+
nil
|
50
|
+
end
|
59
51
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
52
|
+
def process
|
53
|
+
@site[:images] = self.class.site_images(@uri, doc) || []
|
54
|
+
@site[:page_images] = self.class.page_images(@uri, doc) || []
|
55
|
+
other_page_data
|
56
|
+
nil
|
57
|
+
end
|
66
58
|
|
67
|
-
|
68
|
-
|
59
|
+
def report
|
60
|
+
<<~REPORT
|
61
|
+
Site icon: #{@site[:images].first}
|
62
|
+
Page icon: #{@site[:page_images].first}
|
63
|
+
Page title: #{@site[:title]}
|
64
|
+
Page description: #{@site[:description]}
|
65
|
+
Canonical URL: #{@site[:canonical]}
|
66
|
+
REPORT
|
67
|
+
end
|
69
68
|
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
def site_icons
|
70
|
+
@site[:images]
|
71
|
+
end
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
def page_images
|
74
|
+
@site[:page_images]
|
75
|
+
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
canonical = doc.at_xpath("//link[@rel='canonical']/@href")&.value
|
82
|
-
@site.canonical = canonical unless canonical == @url
|
83
|
-
end
|
77
|
+
def title
|
78
|
+
@site[:title]
|
79
|
+
end
|
84
80
|
|
85
|
-
|
86
|
-
|
81
|
+
def description
|
82
|
+
@site[:description]
|
83
|
+
end
|
87
84
|
|
88
|
-
|
89
|
-
|
85
|
+
def other_page_data
|
86
|
+
@site[:title] = doc.at_xpath("//meta[@property='og:title']/@content")&.value || @doc.at_xpath("//title")&.text&.strip
|
87
|
+
@site[:description] = doc.at_xpath("//meta[@property='og:description']/@content")&.value
|
88
|
+
canonical = doc.at_xpath("//link[@rel='canonical']/@href")&.value
|
89
|
+
@site[:canonical] = canonical unless canonical == @url
|
90
|
+
end
|
90
91
|
|
91
|
-
|
92
|
-
|
92
|
+
def self.site_images(uri, doc)
|
93
|
+
results = []
|
94
|
+
|
95
|
+
# Get tile color for Windows tiles
|
96
|
+
tile_color = doc.at_xpath("//meta[@name='msapplication-TileColor']/@content")&.value
|
93
97
|
|
94
|
-
|
95
|
-
|
96
|
-
collect {|e| e.values.select {|v| v =~ /\.png$|\.jpg$|\.gif$|\.ico$|\.svg$|\.ico\?\d*$/ }}.flatten.
|
97
|
-
collect {|v| v[/^http/] || v[/^\//] ? v : '/' + v }.collect {|result| normalise(uri, result)}.uniq.collect {|i| Image.new(i)}.sort {|a, b| a.area <=> b.area }.reverse
|
98
|
-
end
|
98
|
+
paths = "//meta[@name='msapplication-TileImage']|//link[@type='image/ico' or @type='image/vnd.microsoft.icon']|//link[@rel='icon' or @rel='shortcut icon' or @rel='apple-touch-icon-precomposed' or @rel='apple-touch-icon']"
|
99
|
+
results += doc.xpath(paths).collect { |e| e.values.select { |v| v =~ /\.png$|\.jpg$|\.gif$|\.ico$|\.svg$|\.ico\?\d*$/ } }.flatten.collect { |v| (v[/^http/] || v[/^\//]) ? v : "/" + v }
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
101
|
+
results.collect { |result| normalise(uri, result) }.uniq.collect do |url|
|
102
|
+
# Check if this is a tile image to pass the color
|
103
|
+
is_tile = doc.at_xpath("//meta[@name='msapplication-TileImage' and @content='#{url}' or @content='#{url.sub(uri.to_s, '')}']")
|
104
|
+
Image.new(url, is_tile ? tile_color : nil)
|
105
|
+
end.sort_by(&:area).reverse
|
106
|
+
end
|
106
107
|
|
107
|
-
|
108
|
-
|
108
|
+
def self.page_images(uri, doc)
|
109
|
+
doc.xpath("//meta[@property='og:image']")
|
110
|
+
.collect { |e| e.values.reject(&:empty?) }.flatten
|
111
|
+
.collect { |v| (v[/^http/] || v[/^\//]) ? v : "/" + v }.collect { |result| normalise(uri, result) }.uniq.collect { |i| Image.new(i) }.sort_by(&:area).reverse
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.normalise(base, candidate)
|
115
|
+
parsed_candidate = URI(candidate)
|
116
|
+
base = URI(base) unless base.is_a? URI
|
109
117
|
|
118
|
+
parsed_candidate.host = base.host if parsed_candidate.host.nil? # Set relative URLs to absolute
|
119
|
+
parsed_candidate.scheme = base.scheme if parsed_candidate.scheme.nil? # Set the schema if missing
|
120
|
+
|
121
|
+
parsed_candidate.to_s
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def fetch_url(uri)
|
127
|
+
uri = URI(uri) unless uri.is_a?(URI)
|
128
|
+
|
129
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
130
|
+
http.read_timeout = 10
|
131
|
+
http.open_timeout = 5
|
132
|
+
request = Net::HTTP::Get.new(uri)
|
133
|
+
request['User-Agent'] = "Ficon/#{VERSION} (Ruby icon finder; https://github.com/dkam/ficon)"
|
134
|
+
http.request(request)
|
135
|
+
end
|
136
|
+
rescue Net::HTTPError, SocketError, Timeout::Error => e
|
137
|
+
puts "Failed to fetch #{uri}: #{e.inspect}"
|
138
|
+
nil
|
139
|
+
end
|
110
140
|
|
141
|
+
def other_page_data
|
142
|
+
@site[:title] = doc.at_xpath("//meta[@property='og:title']/@content")&.value || @doc.at_xpath("//title")&.text&.strip
|
143
|
+
@site[:description] = doc.at_xpath("//meta[@property='og:description']/@content")&.value
|
144
|
+
canonical = doc.at_xpath("//link[@rel='canonical']/@href")&.value
|
145
|
+
@site[:canonical] = canonical unless canonical == @url
|
111
146
|
end
|
112
|
-
end
|
147
|
+
end
|
data/test/ficon_test.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#require 'rubygems'
|
2
|
-
require '
|
2
|
+
require 'debug'
|
3
3
|
|
4
4
|
require "minitest/autorun"
|
5
5
|
|
@@ -29,22 +29,29 @@ require 'ficon'
|
|
29
29
|
SiteTests << { html: %Q{<link rel="shortcut icon" href="https://fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico" />}, value: 'https://fbstatic-a.akamaihd.net/rsrc.php/yl/r/H3nktOa7ZMg.ico' }
|
30
30
|
SiteTests << { html: %Q{<link rel="icon" type="image/vnd.microsoft.icon" href="/viconline/img/favicon.ico?1393375504" />}, value: 'https://site.com/viconline/img/favicon.ico?1393375504' }
|
31
31
|
SiteTests << { html: %Q{<link rel="shortcut icon" type="image/x-icon" href="/viconline/img/favicon.ico?1393375504" />}, value: 'https://site.com/viconline/img/favicon.ico?1393375504' }
|
32
|
+
SiteTests << { html: %Q{<meta name="msapplication-TileImage" content="/win8-tile-144.png"/><meta name="msapplication-TileColor" content="#00aced"/>}, value: 'https://site.com/win8-tile-144.png' }
|
32
33
|
|
33
34
|
PageTests = []
|
34
35
|
PageTests << { html: %Q{<meta property="og:image" content="https://www.facebook.com/images/fb_icon_325x325.png" />}, value: 'https://www.facebook.com/images/fb_icon_325x325.png' }
|
35
36
|
|
36
37
|
|
37
38
|
class FiconTest < Minitest::Test
|
38
|
-
include Ficon
|
39
39
|
ENV['FICON_DB']=File.join( File.dirname(__FILE__), 'test.db')
|
40
40
|
def test_html_chunks
|
41
41
|
SiteTests.each do |t|
|
42
|
-
result =
|
42
|
+
result = Ficon.site_images('https://site.com', Nokogiri::HTML(t[:html]) )[0]
|
43
43
|
assert result&.url == t[:value], "Seaching |#{t[:html]}| expected #{t[:value]}, got #{result}"
|
44
44
|
end
|
45
45
|
PageTests.each do |t|
|
46
|
-
result =
|
46
|
+
result = Ficon.page_images('https://site.com', Nokogiri::HTML(t[:html]) )[0]
|
47
47
|
assert result&.url == t[:value], "Seaching |#{t[:html]}| expected #{t[:value]}, got #{result}"
|
48
48
|
end
|
49
49
|
end
|
50
|
+
|
51
|
+
def test_tile_color_extraction
|
52
|
+
html = %Q{<meta name="msapplication-TileImage" content="/win8-tile-144.png"/><meta name="msapplication-TileColor" content="#00aced"/>}
|
53
|
+
result = Ficon.site_images('https://site.com', Nokogiri::HTML(html))[0]
|
54
|
+
assert_equal 'https://site.com/win8-tile-144.png', result.url
|
55
|
+
assert_equal '#00aced', result.tile_color
|
56
|
+
end
|
50
57
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ficon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Milne
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: nokogiri
|
@@ -16,112 +15,112 @@ dependencies:
|
|
16
15
|
requirements:
|
17
16
|
- - "~>"
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
18
|
+
version: '1.15'
|
20
19
|
type: :runtime
|
21
20
|
prerelease: false
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
23
22
|
requirements:
|
24
23
|
- - "~>"
|
25
24
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
25
|
+
version: '1.15'
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
27
|
name: addressable
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
30
|
- - "~>"
|
32
31
|
- !ruby/object:Gem::Version
|
33
|
-
version: '2'
|
32
|
+
version: '2.8'
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
37
36
|
requirements:
|
38
37
|
- - "~>"
|
39
38
|
- !ruby/object:Gem::Version
|
40
|
-
version: '2'
|
39
|
+
version: '2.8'
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
41
|
name: fastimage
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
44
|
- - "~>"
|
46
45
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2'
|
46
|
+
version: '2.3'
|
48
47
|
type: :runtime
|
49
48
|
prerelease: false
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
51
50
|
requirements:
|
52
51
|
- - "~>"
|
53
52
|
- !ruby/object:Gem::Version
|
54
|
-
version: '2'
|
53
|
+
version: '2.3'
|
55
54
|
- !ruby/object:Gem::Dependency
|
56
55
|
name: sqlite3
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
58
57
|
requirements:
|
59
58
|
- - "~>"
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
60
|
+
version: '2.0'
|
62
61
|
type: :runtime
|
63
62
|
prerelease: false
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
65
64
|
requirements:
|
66
65
|
- - "~>"
|
67
66
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
67
|
+
version: '2.0'
|
69
68
|
- !ruby/object:Gem::Dependency
|
70
69
|
name: bundler
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
72
71
|
requirements:
|
73
72
|
- - "~>"
|
74
73
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
74
|
+
version: '2.0'
|
76
75
|
type: :development
|
77
76
|
prerelease: false
|
78
77
|
version_requirements: !ruby/object:Gem::Requirement
|
79
78
|
requirements:
|
80
79
|
- - "~>"
|
81
80
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
81
|
+
version: '2.0'
|
83
82
|
- !ruby/object:Gem::Dependency
|
84
83
|
name: rake
|
85
84
|
requirement: !ruby/object:Gem::Requirement
|
86
85
|
requirements:
|
87
86
|
- - "~>"
|
88
87
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
88
|
+
version: '13.0'
|
90
89
|
type: :development
|
91
90
|
prerelease: false
|
92
91
|
version_requirements: !ruby/object:Gem::Requirement
|
93
92
|
requirements:
|
94
93
|
- - "~>"
|
95
94
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
95
|
+
version: '13.0'
|
97
96
|
- !ruby/object:Gem::Dependency
|
98
97
|
name: minitest
|
99
98
|
requirement: !ruby/object:Gem::Requirement
|
100
99
|
requirements:
|
101
100
|
- - "~>"
|
102
101
|
- !ruby/object:Gem::Version
|
103
|
-
version: '5'
|
102
|
+
version: '5.0'
|
104
103
|
type: :development
|
105
104
|
prerelease: false
|
106
105
|
version_requirements: !ruby/object:Gem::Requirement
|
107
106
|
requirements:
|
108
107
|
- - "~>"
|
109
108
|
- !ruby/object:Gem::Version
|
110
|
-
version: '5'
|
109
|
+
version: '5.0'
|
111
110
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
111
|
+
name: debug
|
113
112
|
requirement: !ruby/object:Gem::Requirement
|
114
113
|
requirements:
|
115
114
|
- - "~>"
|
116
115
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
116
|
+
version: '1.0'
|
118
117
|
type: :development
|
119
118
|
prerelease: false
|
120
119
|
version_requirements: !ruby/object:Gem::Requirement
|
121
120
|
requirements:
|
122
121
|
- - "~>"
|
123
122
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
123
|
+
version: '1.0'
|
125
124
|
description: Ficon finds icons for websites and optionally, the best icon
|
126
125
|
email:
|
127
126
|
- d@nmilne.com
|
@@ -146,7 +145,6 @@ homepage: https://github.com/dkam/ficon
|
|
146
145
|
licenses:
|
147
146
|
- MIT
|
148
147
|
metadata: {}
|
149
|
-
post_install_message:
|
150
148
|
rdoc_options: []
|
151
149
|
require_paths:
|
152
150
|
- lib
|
@@ -154,16 +152,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
154
152
|
requirements:
|
155
153
|
- - ">="
|
156
154
|
- !ruby/object:Gem::Version
|
157
|
-
version: '0'
|
155
|
+
version: '3.0'
|
158
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
157
|
requirements:
|
160
158
|
- - ">="
|
161
159
|
- !ruby/object:Gem::Version
|
162
160
|
version: '0'
|
163
161
|
requirements: []
|
164
|
-
|
165
|
-
rubygems_version: 2.6.11
|
166
|
-
signing_key:
|
162
|
+
rubygems_version: 3.6.9
|
167
163
|
specification_version: 4
|
168
164
|
summary: Find website icons
|
169
165
|
test_files:
|