Module: FaviconGem

Defined in:
lib/favicon_gem.rb,
lib/favicon_gem/version.rb

Defined Under Namespace

Classes: Error, Icon

Constant Summary collapse

TITLE =

Gem metadata

"favicon_gem"
AUTHOR =
"Ported from Python favicon by Scott Werner"
LICENSE =
"MIT"
HEADERS =
{
  "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) " \
                 "AppleWebKit/537.36 (KHTML, like Gecko) " \
                 "Chrome/33.0.1750.152 Safari/537.36"
}
[
  "icon",
  "shortcut icon",
  "apple-touch-icon",
  "apple-touch-icon-precomposed"
]
META_NAMES =

Removed og:image from metatags as it’s usually not a favicon

["msapplication-TileImage"]
FORMAT_PRIORITY =

Format priorities (higher = better)

{
  "ico" => 10,
  "png" => 9,
  "jpg" => 8,
  "jpeg" => 7,
  "svg" => 6,
  "gif" => 5,
  "" => 0  # Unknown format has the lowest priority
}
SIZE_RE =
/(?<width>\d{2,4})x(?<height>\d{2,4})/i
VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.get(url, headers: HEADERS, **request_options) ⇒ Array<Icon>

Get all icons for a URL

Parameters:

  • url (String)

    Page URL

  • headers (Hash) (defaults to: HEADERS)

    Request headers

Returns:

  • (Array<Icon>)

    List of found icons, sorted by size

Raises:



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
# File 'lib/favicon_gem.rb', line 55

def get(url, headers: HEADERS, **request_options)
  request_options[:headers] ||= headers

  conn = Faraday.new(url: url) do |faraday|
    faraday.request :url_encoded
    faraday.headers = request_options[:headers]
    faraday.options.timeout = request_options[:timeout] if request_options[:timeout]
    faraday.use Faraday::FollowRedirects::Middleware
    faraday.adapter Faraday.default_adapter
  end

  response = conn.get
  raise Error, "Failed to fetch URL: #{response.status}" unless response.success?

  icons = Set.new

  default_icon = default(response.env.url.to_s, **request_options)
  icons.add(default_icon) if default_icon

  link_icons = tags(response.env.url.to_s, response.body)
  icons.merge(link_icons) if link_icons.any?

  # Improve sorting:
  # 1. By size (larger first)
  # 2. If sizes are equal, sort by format (ico/png have higher priority)
  # 3. All icons with zero sizes go to the end
  icons.to_a.sort_by do |icon|
    format_priority = FORMAT_PRIORITY[icon.format] || 0
    size = icon.width + icon.height

    if size > 0
      [1, size, format_priority]  # Icons with non-zero size first
    else
      [0, format_priority]        # Zero sizes - second priority
    end
  end.reverse
end