/
provider.rb
115 lines (94 loc) · 2.8 KB
/
provider.rb
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
require 'open-uri'
require 'multi_json'
require 'addressable/uri'
class VideoInfo
class Provider
attr_accessor :url, :options, :iframe_attributes, :video_id, :data
def initialize(url, options = {})
@options = _clean_options(options)
@url = url
_set_video_id_from_url
end
def self.usable?(url)
raise NotImplementedError.new(
'Provider class must implement .usable? public method'
)
end
def embed_code(options = {})
iframe_attributes = options.fetch(:iframe_attributes, {})
iframe_attrs = ["src=\"#{_embed_url(options)}\"", "frameborder=\"0\""]
iframe_attrs << _hash_to_attributes(
_default_iframe_attributes.merge(iframe_attributes)
)
"<iframe #{iframe_attrs.reject(&:empty?).join(" ")}></iframe>"
end
def data
@data ||= _set_data_from_api
end
def available?
!%w[403 404].include?(_response_code)
end
private
def _response_code
response = nil
Net::HTTP.start(_api_base, 80) { |http| response = http.head(_api_path) }
response.code
end
def _clean_options(options)
options =
{ 'User-Agent' => "VideoInfo/#{VideoInfo::VERSION}" }.merge(options)
options.dup.each do |key, value|
if _not_openuri_option_symbol?(key)
options[_http_header_field(key)] = value
options.delete key
end
end
options
end
def _set_data_from_api(api_url = _api_url)
uri = open(api_url, options)
MultiJson.load(uri.read)
end
def _not_openuri_option_symbol?(key)
key.is_a?(Symbol) && !OpenURI::Options.keys.include?(key)
end
def _http_header_field(key)
key.to_s.split(/[^a-z]/i).map(&:capitalize).join('-')
end
def _set_video_id_from_url
@url.gsub(_url_regex) { @video_id = $1 || $2 || $3 }
unless _valid_video_id?
raise UrlError, "Url is not valid, video_id is not found: #{url}"
end
end
def _valid_video_id?
video_id && video_id != url && !video_id.empty?
end
def _url_regex
raise NotImplementedError.new(
'Provider class must implement #_url_regex private method'
)
end
def _api_url
raise NotImplementedError.new(
'Provider class must implement #_api_url private method'
)
end
def _embed_url(options)
url_attrs = options.fetch(:url_attributes, {})
url_attrs = _default_url_attributes.merge(url_attrs)
url = embed_url
url += "?#{_hash_to_params(url_attrs)}" unless url_attrs.empty?
url
end
def _hash_to_attributes(hash)
return unless hash.is_a?(Hash)
hash.map { |k, v| "#{k}=\"#{v}\"" }.join(' ')
end
def _hash_to_params(hash)
uri = Addressable::URI.new
uri.query_values = hash
uri.query
end
end
end