onebox 2.2.9 → 2.2.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -4
  3. data/lib/onebox/engine.rb +1 -1
  4. data/lib/onebox/engine/allowlisted_generic_onebox.rb +11 -9
  5. data/lib/onebox/engine/amazon_onebox.rb +25 -13
  6. data/lib/onebox/engine/asciinema_onebox.rb +0 -1
  7. data/lib/onebox/engine/audioboom_onebox.rb +5 -2
  8. data/lib/onebox/engine/bandcamp_onebox.rb +8 -8
  9. data/lib/onebox/engine/cloudapp_onebox.rb +12 -12
  10. data/lib/onebox/engine/coub_onebox.rb +0 -1
  11. data/lib/onebox/engine/facebook_media_onebox.rb +8 -7
  12. data/lib/onebox/engine/five_hundred_px_onebox.rb +0 -1
  13. data/lib/onebox/engine/flickr_onebox.rb +14 -15
  14. data/lib/onebox/engine/giphy_onebox.rb +0 -1
  15. data/lib/onebox/engine/github_blob_onebox.rb +4 -0
  16. data/lib/onebox/engine/github_commit_onebox.rb +12 -15
  17. data/lib/onebox/engine/github_gist_onebox.rb +1 -2
  18. data/lib/onebox/engine/github_issue_onebox.rb +16 -18
  19. data/lib/onebox/engine/github_pullrequest_onebox.rb +9 -1
  20. data/lib/onebox/engine/gitlab_blob_onebox.rb +4 -0
  21. data/lib/onebox/engine/google_calendar_onebox.rb +1 -1
  22. data/lib/onebox/engine/google_docs_onebox.rb +7 -7
  23. data/lib/onebox/engine/google_drive_onebox.rb +7 -7
  24. data/lib/onebox/engine/google_maps_onebox.rb +0 -2
  25. data/lib/onebox/engine/google_photos_onebox.rb +14 -14
  26. data/lib/onebox/engine/google_play_app_onebox.rb +3 -7
  27. data/lib/onebox/engine/html.rb +4 -1
  28. data/lib/onebox/engine/instagram_onebox.rb +2 -2
  29. data/lib/onebox/engine/kaltura_onebox.rb +8 -6
  30. data/lib/onebox/engine/opengraph_image.rb +0 -1
  31. data/lib/onebox/engine/pubmed_onebox.rb +3 -2
  32. data/lib/onebox/engine/replit_onebox.rb +0 -1
  33. data/lib/onebox/engine/sketchfab_onebox.rb +8 -8
  34. data/lib/onebox/engine/slides_onebox.rb +10 -10
  35. data/lib/onebox/engine/soundcloud_onebox.rb +0 -1
  36. data/lib/onebox/engine/stack_exchange_onebox.rb +2 -1
  37. data/lib/onebox/engine/standard_embed.rb +2 -2
  38. data/lib/onebox/engine/steam_store_onebox.rb +6 -5
  39. data/lib/onebox/engine/trello_onebox.rb +2 -2
  40. data/lib/onebox/engine/twitch_clips_onebox.rb +1 -3
  41. data/lib/onebox/engine/twitch_stream_onebox.rb +1 -2
  42. data/lib/onebox/engine/twitch_video_onebox.rb +0 -2
  43. data/lib/onebox/engine/typeform_onebox.rb +7 -6
  44. data/lib/onebox/engine/vimeo_onebox.rb +9 -7
  45. data/lib/onebox/engine/wikimedia_onebox.rb +1 -2
  46. data/lib/onebox/engine/wikipedia_onebox.rb +12 -8
  47. data/lib/onebox/engine/youku_onebox.rb +7 -7
  48. data/lib/onebox/engine/youtube_onebox.rb +46 -17
  49. data/lib/onebox/file_type_finder.rb +0 -1
  50. data/lib/onebox/helpers.rb +3 -3
  51. data/lib/onebox/mixins/git_blob_onebox.rb +5 -3
  52. data/lib/onebox/mixins/github_body.rb +30 -0
  53. data/lib/onebox/mixins/twitch_onebox.rb +0 -1
  54. data/lib/onebox/preview.rb +1 -2
  55. data/lib/onebox/sanitize_config.rb +1 -1
  56. data/lib/onebox/version.rb +1 -1
  57. data/templates/github/github_body.mustache +5 -0
  58. data/templates/githubcommit.mustache +2 -8
  59. data/templates/githubissue.mustache +7 -9
  60. data/templates/githubpullrequest.mustache +2 -1
  61. metadata +4 -2
@@ -37,7 +37,7 @@ module Onebox
37
37
  end
38
38
 
39
39
  def raw
40
- return @raw if @raw
40
+ return @raw if defined?(@raw)
41
41
 
42
42
  og = get_opengraph
43
43
  twitter = get_twitter
@@ -67,7 +67,7 @@ module Onebox
67
67
  protected
68
68
 
69
69
  def html_doc
70
- return @html_doc if @html_doc
70
+ return @html_doc if defined?(@html_doc)
71
71
 
72
72
  headers = nil
73
73
  headers = { 'Cookie' => options[:cookie] } if options[:cookie]
@@ -28,11 +28,12 @@ module Onebox
28
28
  escaped_src = ::Onebox::Helpers.normalize_url_for_output(iframe_url)
29
29
 
30
30
  <<-HTML
31
- <iframe src='#{escaped_src}'
32
- frameborder='0'
33
- width='100%'
34
- height='190'>
35
- </iframe>
31
+ <iframe
32
+ src='#{escaped_src}'
33
+ frameborder='0'
34
+ width='100%'
35
+ height='190'
36
+ ></iframe>
36
37
  HTML
37
38
  end
38
39
  end
@@ -16,7 +16,7 @@ module Onebox
16
16
  height = match[:type] == 'b' ? 400 : 200
17
17
 
18
18
  <<-HTML
19
- <iframe src=\"#{link}\" width=\"100%\" height=\"#{height}\" frameborder=\"0\" style=\"border:0\"></iframe>
19
+ <iframe src="#{link}" width="100%" height="#{height}" frameborder="0" style="border:0"></iframe>
20
20
  HTML
21
21
  end
22
22
 
@@ -26,7 +26,7 @@ module Onebox
26
26
 
27
27
  private
28
28
  def match
29
- return @match if @match
29
+ return @match if defined?(@match)
30
30
 
31
31
  @match = @url.match(%{trello\.com/(?<type>[^/]+)/(?<key>[^/]+)/?\W*})
32
32
 
@@ -3,12 +3,11 @@
3
3
  require_relative '../mixins/twitch_onebox'
4
4
 
5
5
  class Onebox::Engine::TwitchClipsOnebox
6
-
7
6
  def self.twitch_regexp
8
7
  /^https?:\/\/clips\.twitch\.tv\/([a-zA-Z0-9_]+\/?[^#\?\/]+)/
9
8
  end
10
- include Onebox::Mixins::TwitchOnebox
11
9
 
10
+ include Onebox::Mixins::TwitchOnebox
12
11
  requires_iframe_origins "https://clips.twitch.tv"
13
12
 
14
13
  def query_params
@@ -18,5 +17,4 @@ class Onebox::Engine::TwitchClipsOnebox
18
17
  def base_url
19
18
  "clips.twitch.tv/embed?"
20
19
  end
21
-
22
20
  end
@@ -3,14 +3,13 @@
3
3
  require_relative '../mixins/twitch_onebox'
4
4
 
5
5
  class Onebox::Engine::TwitchStreamOnebox
6
-
7
6
  def self.twitch_regexp
8
7
  /^https?:\/\/(?:www\.|go\.)?twitch\.tv\/(?!directory)([a-zA-Z0-9_]{4,25})$/
9
8
  end
9
+
10
10
  include Onebox::Mixins::TwitchOnebox
11
11
 
12
12
  def query_params
13
13
  "channel=#{twitch_id}"
14
14
  end
15
-
16
15
  end
@@ -3,7 +3,6 @@
3
3
  require_relative '../mixins/twitch_onebox'
4
4
 
5
5
  class Onebox::Engine::TwitchVideoOnebox
6
-
7
6
  def self.twitch_regexp
8
7
  /^https?:\/\/(?:www\.)?twitch\.tv\/videos\/([0-9]+)/
9
8
  end
@@ -13,5 +12,4 @@ class Onebox::Engine::TwitchVideoOnebox
13
12
  def query_params
14
13
  "video=v#{twitch_id}"
15
14
  end
16
-
17
15
  end
@@ -13,12 +13,13 @@ module Onebox
13
13
  typeform_src = build_typeform_src
14
14
 
15
15
  <<~HTML
16
- <iframe src="#{typeform_src}"
17
- width="100%"
18
- height="600px"
19
- scrolling="no"
20
- frameborder="0">
21
- </iframe>
16
+ <iframe
17
+ src="#{typeform_src}"
18
+ width="100%"
19
+ height="600px"
20
+ scrolling="no"
21
+ frameborder="0"
22
+ ></iframe>
22
23
  HTML
23
24
  end
24
25
 
@@ -25,14 +25,16 @@ module Onebox
25
25
  end
26
26
  video_src = "https://player.vimeo.com/video/#{video_id}"
27
27
  video_src = video_src.gsub('autoplay=1', '').chomp("?")
28
+
28
29
  <<-HTML
29
- <iframe width="#{WIDTH}"
30
- height="#{HEIGHT}"
31
- src="#{video_src}"
32
- data-original-href="#{link}"
33
- frameborder="0"
34
- allowfullscreen>
35
- </iframe>
30
+ <iframe
31
+ width="#{WIDTH}"
32
+ height="#{HEIGHT}"
33
+ src="#{video_src}"
34
+ data-original-href="#{link}"
35
+ frameborder="0"
36
+ allowfullscreen
37
+ ></iframe>
36
38
  HTML
37
39
  end
38
40
 
@@ -7,7 +7,7 @@ module Onebox
7
7
  include LayoutSupport
8
8
  include JSON
9
9
 
10
- matches_regexp /^https?:\/\/commons\.wikimedia\.org\/wiki\/(File:.+)/
10
+ matches_regexp(/^https?:\/\/commons\.wikimedia\.org\/wiki\/(File:.+)/)
11
11
  always_https
12
12
 
13
13
  def self.priority
@@ -38,7 +38,6 @@ module Onebox
38
38
  thumbnail: first_page['imageinfo'].first['thumburl']
39
39
  }
40
40
  end
41
-
42
41
  end
43
42
  end
44
43
  end
@@ -16,10 +16,10 @@ module Onebox
16
16
  paras = []
17
17
  text = ""
18
18
 
19
- # Detect section Hash in the url and retrive the related paragraphs. if no hash provided the first few paragraphs will be used
19
+ # Detect section Hash in the url and retrive the related paragraphs. if no hash provided the first few paragraphs will be used
20
20
  # Author Lidlanca
21
21
  # Date 9/8/2014
22
- if (m_url_hash = @url.match(/#([^\/?]+)/)) #extract url hash
22
+ if (m_url_hash = @url.match(/#([^\/?]+)/)) # extract url hash
23
23
  m_url_hash_name = m_url_hash[1]
24
24
  end
25
25
 
@@ -27,17 +27,17 @@ module Onebox
27
27
  section_header_title = raw.xpath("//span[@id='#{m_url_hash_name}']")
28
28
 
29
29
  if section_header_title.empty?
30
- paras = raw.search("p") #default get all the paras
30
+ paras = raw.search("p") # default get all the paras
31
31
  else
32
32
  section_title_text = section_header_title.inner_text
33
- section_header = section_header_title[0].parent #parent element of the section span element should be an <h3> node
33
+ section_header = section_header_title[0].parent # parent element of the section span element should be an <h3> node
34
34
  cur_element = section_header
35
35
 
36
- # p|text|div covers the general case. We assume presence of atleast 1 P node. if section has no P node we may end up with a P node from the next section.
36
+ # p|text|div covers the general case. We assume presence of at least 1 P node. if section has no P node we may end up with a P node from the next section.
37
37
  # div tag is commonly used as an assets wraper in an article section. often as the first element holding an image.
38
38
  # ul support will imporve the output generated for a section with a list as the main content (for example: an Author Bibliography, A musician Discography, etc)
39
39
  first_p_found = nil
40
- while (((next_sibling = cur_element.next_sibling).name =~ /p|text|div|ul/) || first_p_found.nil?) do #from section header get the next sibling until it is a breaker tag
40
+ while (((next_sibling = cur_element.next_sibling).name =~ /p|text|div|ul/) || first_p_found.nil?) do # from section header get the next sibling until it is a breaker tag
41
41
  cur_element = next_sibling
42
42
  if (cur_element.name == "p" || cur_element.name == "ul") #we treat a list as we detect a p to avoid showing
43
43
  first_p_found = true
@@ -46,7 +46,7 @@ module Onebox
46
46
  end
47
47
  end
48
48
  else # no hash found in url
49
- paras = raw.search("p") #default get all the paras
49
+ paras = raw.search("p") # default get all the paras
50
50
  end
51
51
 
52
52
  unless paras.empty?
@@ -55,7 +55,7 @@ module Onebox
55
55
  break if cnt >= paras.size
56
56
  text += " " unless cnt == 0
57
57
 
58
- if paras[cnt].name == "ul" #Handle UL tag. Generate a textual ordered list (1.item | 2.item | 3.item). Unfourtently no newline allowed in output
58
+ if paras[cnt].name == "ul" # Handle UL tag. Generate a textual ordered list (1.item | 2.item | 3.item). Unfortunately no newline allowed in output
59
59
  li_index = 1
60
60
  list_items = []
61
61
  paras[cnt].children.css("li").each { |li| list_items.push "#{li_index}." + li.inner_text ; li_index += 1 }
@@ -69,13 +69,17 @@ module Onebox
69
69
  cnt += 1
70
70
  end
71
71
  end
72
+
72
73
  text = "#{text[0..Onebox::LayoutSupport.max_text]}..." if text.length > Onebox::LayoutSupport.max_text
74
+
73
75
  result = {
74
76
  link: link,
75
77
  title: raw.css("html body h1").inner_text + (section_title_text ? " | " + section_title_text : ""), #if a section sub title exists add it to the main article title
76
78
  description: text
77
79
  }
80
+
78
81
  img = raw.css(".image img")
82
+
79
83
  if img && img.size > 0
80
84
  img.each do |i|
81
85
  src = i["src"]
@@ -21,12 +21,13 @@ module Onebox
21
21
 
22
22
  def to_html
23
23
  <<~HTML
24
- <iframe src="https://player.youku.com/embed/#{video_id}"
25
- width="640"
26
- height="430"
27
- frameborder='0'
28
- allowfullscreen>
29
- </iframe>
24
+ <iframe
25
+ src="https://player.youku.com/embed/#{video_id}"
26
+ width="640"
27
+ height="430"
28
+ frameborder='0'
29
+ allowfullscreen
30
+ ></iframe>
30
31
  HTML
31
32
  end
32
33
 
@@ -35,7 +36,6 @@ module Onebox
35
36
  def uri
36
37
  @_uri ||= URI(@url)
37
38
  end
38
-
39
39
  end
40
40
  end
41
41
  end
@@ -13,11 +13,36 @@ module Onebox
13
13
  WIDTH ||= 480
14
14
  HEIGHT ||= 360
15
15
 
16
- def placeholder_html
17
- og = get_opengraph.data
16
+ def parse_embed_response
17
+ return unless video_id
18
+ return @parse_embed_response if defined?(@parse_embed_response)
19
+
20
+ embed_url = "https://www.youtube.com/embed/#{video_id}"
21
+ @embed_doc ||= Onebox::Helpers.fetch_html_doc(embed_url)
22
+
23
+ begin
24
+ script_tag = @embed_doc.xpath('//script').find { |tag| tag.to_s.include?('ytcfg.set') }.to_s
25
+ match = script_tag.to_s.match(/ytcfg\.set\((?<json>.*)\)/)
26
+
27
+ yt_json = ::JSON.parse(match[:json])
28
+ renderer = ::JSON.parse(yt_json['PLAYER_VARS']['embedded_player_response'])['embedPreview']['thumbnailPreviewRenderer']
29
+
30
+ title = renderer['title']['runs'].first['text']
31
+
32
+ image = "https://img.youtube.com/vi/#{video_id}/hqdefault.jpg"
33
+ rescue
34
+ return
35
+ end
18
36
 
37
+ @parse_embed_response = { image: image, title: title }
38
+ end
39
+
40
+ def placeholder_html
19
41
  if video_id || list_id
20
- "<img src='#{og[:image]}' width='#{WIDTH}' height='#{HEIGHT}' title='#{og[:title]}'>"
42
+ result = parse_embed_response
43
+ result ||= get_opengraph.data
44
+
45
+ "<img src='#{result[:image]}' width='#{WIDTH}' height='#{HEIGHT}' title='#{result[:title]}'>"
21
46
  else
22
47
  to_html
23
48
  end
@@ -26,21 +51,23 @@ module Onebox
26
51
  def to_html
27
52
  if video_id
28
53
  <<-HTML
29
- <iframe width="#{WIDTH}"
30
- height="#{HEIGHT}"
31
- src="https://www.youtube.com/embed/#{video_id}?#{embed_params}"
32
- frameborder="0"
33
- allowfullscreen>
34
- </iframe>
54
+ <iframe
55
+ src="https://www.youtube.com/embed/#{video_id}?#{embed_params}"
56
+ width="#{WIDTH}"
57
+ height="#{HEIGHT}"
58
+ frameborder="0"
59
+ allowfullscreen
60
+ ></iframe>
35
61
  HTML
36
62
  elsif list_id
37
63
  <<-HTML
38
- <iframe width="#{WIDTH}"
39
- height="#{HEIGHT}"
40
- src="https://www.youtube.com/embed/videoseries?list=#{list_id}&wmode=transparent&rel=0&autohide=1&showinfo=1&enablejsapi=1"
41
- frameborder="0"
42
- allowfullscreen>
43
- </iframe>
64
+ <iframe
65
+ src="https://www.youtube.com/embed/videoseries?list=#{list_id}&wmode=transparent&rel=0&autohide=1&showinfo=1&enablejsapi=1"
66
+ width="#{WIDTH}"
67
+ height="#{HEIGHT}"
68
+ frameborder="0"
69
+ allowfullscreen
70
+ ></iframe>
44
71
  HTML
45
72
  else
46
73
  # for channel pages
@@ -52,7 +79,10 @@ module Onebox
52
79
  end
53
80
 
54
81
  def video_title
55
- @video_title ||= get_opengraph.data[:title]
82
+ @video_title ||= begin
83
+ result = parse_embed_response || get_opengraph.data
84
+ result[:title]
85
+ end
56
86
  end
57
87
 
58
88
  private
@@ -138,7 +168,6 @@ module Onebox
138
168
  rescue
139
169
  {}
140
170
  end
141
-
142
171
  end
143
172
  end
144
173
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Onebox
4
4
  module FileTypeFinder
5
-
6
5
  # In general, most of file extension names would be recognized
7
6
  # by Highlights.js. However, some need to be checked in other
8
7
  # ways, either because they just aren't included, because they
@@ -7,7 +7,7 @@ module Onebox
7
7
 
8
8
  class DownloadTooLarge < StandardError; end
9
9
 
10
- IGNORE_CANONICAL_DOMAINS ||= ['www.instagram.com']
10
+ IGNORE_CANONICAL_DOMAINS ||= ['www.instagram.com', 'youtube.com']
11
11
 
12
12
  def self.symbolize_keys(hash)
13
13
  return {} if hash.nil?
@@ -127,10 +127,10 @@ module Onebox
127
127
 
128
128
  http.request_head([uri.path, uri.query].join("?")) do |response|
129
129
  code = response.code.to_i
130
- unless code === 200 || Onebox::Helpers.blank?(response.header['content-length'])
130
+ unless code === 200 || Onebox::Helpers.blank?(response.content_length)
131
131
  return nil
132
132
  end
133
- return response.header['content-length']
133
+ return response.content_length
134
134
  end
135
135
  end
136
136
  end
@@ -33,6 +33,10 @@ module Onebox
33
33
 
34
34
  self.options = DEFAULTS
35
35
 
36
+ @selected_lines_array = nil
37
+ @selected_one_liner = 0
38
+ @model_file = nil
39
+
36
40
  # Define constant after merging options set in Onebox.options
37
41
  # We can define constant automatically.
38
42
  options.each_pair do |constant_name, value|
@@ -47,8 +51,6 @@ module Onebox
47
51
  end
48
52
 
49
53
  private
50
- @selected_lines_array = nil
51
- @selected_one_liner = 0
52
54
 
53
55
  def calc_range(m, contents_lines_size)
54
56
  truncated = false
@@ -150,7 +152,7 @@ module Onebox
150
152
  end
151
153
 
152
154
  def raw
153
- return @raw if @raw
155
+ return @raw if defined?(@raw)
154
156
 
155
157
  m = @url.match(self.raw_regexp)
156
158
 
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onebox
4
+ module Mixins
5
+ module GithubBody
6
+ def self.included(klass)
7
+ klass.include(Onebox::Engine)
8
+ klass.include(InstanceMethods)
9
+ end
10
+
11
+ module InstanceMethods
12
+ GITHUB_COMMENT_REGEX = /(<!--.*?-->\r\n)/
13
+ MAX_BODY_LENGTH = 80
14
+ def compute_body(body)
15
+ body = body.dup
16
+ excerpt = nil
17
+
18
+ body = (body || '').gsub(GITHUB_COMMENT_REGEX, '')
19
+ body = body.length > 0 ? body : nil
20
+ if body && body.length > MAX_BODY_LENGTH
21
+ excerpt = body[MAX_BODY_LENGTH..body.length].rstrip
22
+ body = body[0..MAX_BODY_LENGTH - 1]
23
+ end
24
+
25
+ [body, excerpt]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end