onebox 1.5.5 → 1.5.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af8a0c496cbfd1be8549197491c181e80dc5423d
4
- data.tar.gz: 907eb2132907a74bcd7e54e35e359757c24714ce
3
+ metadata.gz: ff1798c506e288427056ead18fd48f2988050be3
4
+ data.tar.gz: ba7f2a9b90eca120f7e02823dd82478efd82b23d
5
5
  SHA512:
6
- metadata.gz: aa9c7b77f9c7817a2713f625f5c0ae32a5cccdb7db48d2da0ab71d7696f8aa9e610e22975c810d4202937e81dce676a2115ead91a2b904bf6925f8c08244cc7d
7
- data.tar.gz: 125ee9336e3a685736ea39b12e5e8dfe20682146ff970afcb3a75596f169e90a0ec9a6e63b900e50207ac67b474551682dffd2e228ad4675bcf3785dce63a59d
6
+ metadata.gz: 5cefe833b7afd031180985fec397fa7f42704c5c2a8e456260d756805bb4741db9b3a8496556d1a841009b9eda5445c243487f9b30acbe7cff89e2beba06d69b
7
+ data.tar.gz: d22d9b5ed23f70cde5d8e3bdf8e272c9c5aafb6d4dc989e3db604f8d9b1ed9f010803aa01a00600cd885724056201e8b9f5b517065467960a5e72918dc26ca20
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  *.gem
2
2
  *.rbc
3
3
  .bundle
4
+ /.idea
4
5
  .config
5
6
  .yardoc
6
7
  Gemfile.lock
data/lib/onebox/engine.rb CHANGED
@@ -13,29 +13,29 @@ module Onebox
13
13
  attr_reader :url
14
14
  attr_reader :cache
15
15
  attr_reader :timeout
16
-
16
+
17
17
  DEFUALT = {}
18
18
  def options
19
19
  @options
20
20
  end
21
-
21
+
22
22
  def options=(opt)
23
23
  return @options if opt.nil? #make sure options provided
24
24
  if opt.instance_of? OpenStruct
25
- @options = @options.merge(opt.to_h)
25
+ @options = @options.merge(opt.to_h)
26
26
  else
27
27
  @options = @options.merge(opt)
28
28
  end
29
29
  @options
30
30
  end
31
-
31
+
32
32
 
33
33
  def initialize(link, cache = nil, timeout = nil)
34
-
34
+
35
35
  @options = DEFUALT
36
36
  class_name = self.class.name.split("::").last.to_s
37
37
  self.options = Onebox.options[class_name] || {} #Set the engine options extracted from global options.
38
-
38
+
39
39
  @url = link
40
40
  @cache = cache || Onebox.options.cache
41
41
  @timeout = timeout || Onebox.options.timeout
@@ -118,6 +118,7 @@ end
118
118
 
119
119
  require_relative "helpers"
120
120
  require_relative "layout_support"
121
+ require_relative "file_type_finder"
121
122
  require_relative "engine/standard_embed"
122
123
  require_relative "engine/html"
123
124
  require_relative "engine/json"
@@ -126,17 +127,17 @@ require_relative "engine/classic_google_maps_onebox"
126
127
  require_relative "engine/github_issue_onebox"
127
128
  require_relative "engine/github_blob_onebox"
128
129
  require_relative "engine/github_commit_onebox"
129
- # broken
130
- #require_relative "engine/github_gist_onebox"
130
+ require_relative "engine/github_gist_onebox"
131
131
  require_relative "engine/github_pullrequest_onebox"
132
132
  require_relative "engine/google_play_app_onebox"
133
133
  require_relative "engine/image_onebox"
134
+ require_relative "engine/video_onebox"
135
+ require_relative "engine/audio_onebox"
134
136
  require_relative "engine/stack_exchange_onebox"
135
137
  require_relative "engine/twitter_status_onebox"
136
138
  require_relative "engine/wikipedia_onebox"
137
139
  require_relative "engine/youtube_onebox"
140
+ require_relative "engine/youku_onebox"
138
141
  require_relative "engine/douban_onebox"
139
142
  require_relative "engine/whitelisted_generic_onebox"
140
143
  require_relative "engine/pubmed_onebox"
141
- require_relative "engine/video_onebox"
142
- require_relative "engine/audio_onebox"
@@ -4,10 +4,10 @@ module Onebox
4
4
  include Engine
5
5
  include LayoutSupport
6
6
 
7
- EXPAND_AFTER = 0b001
7
+ EXPAND_AFTER = 0b001
8
8
  EXPAND_BEFORE = 0b010
9
9
  EXPAND_NONE = 0b0
10
-
10
+
11
11
  DEFAULTS = {
12
12
  :EXPAND_ONE_LINER => EXPAND_AFTER|EXPAND_BEFORE, #set how to expand a one liner. user EXPAND_NONE to disable expand
13
13
  :LINES_BEFORE => 10,
@@ -16,7 +16,7 @@ module Onebox
16
16
  :MAX_LINES => 20,
17
17
  :MAX_CHARS => 5000
18
18
  }
19
-
19
+
20
20
  matches_regexp(/^https?:\/\/(www\.)?github\.com.*\/blob\//)
21
21
 
22
22
 
@@ -25,12 +25,12 @@ module Onebox
25
25
  super link, cache , timeout
26
26
  #merge engine options from global Onebox.options interface
27
27
  # self.options = Onebox.options["GithubBlobOnebox"] # self.class.name.split("::").last.to_s
28
- # self.options = Onebox.options[self.class.name.split("::").last.to_s] #We can use this a more generic approach. extract the engine class name automatically
29
-
28
+ # self.options = Onebox.options[self.class.name.split("::").last.to_s] #We can use this a more generic approach. extract the engine class name automatically
29
+
30
30
  self.options = DEFAULTS
31
31
 
32
32
  # Define constant after merging options set in Onebox.options
33
- # We can define constant automatically.
33
+ # We can define constant automatically.
34
34
  options.each_pair {|constant_name,value|
35
35
  constant_name_u = constant_name.to_s.upcase
36
36
  if constant_name_u == constant_name.to_s
@@ -51,7 +51,7 @@ module Onebox
51
51
  range_provided = !(from.nil? && to.nil?) #true if "from" or "to" provided in URL
52
52
  from = from.nil? ? 1 : from[0].to_i #if from not provided default to 1st line
53
53
  to = to.nil? ? -1 : to[0].to_i #if to not provided default to undefiend to be handled later in the logic
54
-
54
+
55
55
  if to === -1 && range_provided #case "from" exists but no valid "to". aka ONE_LINER
56
56
  one_liner = true
57
57
  to = from
@@ -60,7 +60,7 @@ module Onebox
60
60
  end
61
61
 
62
62
  unless range_provided #case no range provided default to 1..MAX_LINES
63
- from = 1
63
+ from = 1
64
64
  to = MAX_LINES
65
65
  truncated = true if contents_lines_size > MAX_LINES
66
66
  #we can technically return here
@@ -69,7 +69,7 @@ module Onebox
69
69
  from, to = [from,to].sort #enforce valid range. [from < to]
70
70
  from = 1 if from > contents_lines_size #if "from" out of TOP bound set to 1st line
71
71
  to = contents_lines_size if to > contents_lines_size #if "to" is out of TOP bound set to last line.
72
-
72
+
73
73
  if one_liner
74
74
  @selected_one_liner = from
75
75
  if EXPAND_ONE_LINER != EXPAND_NONE
@@ -81,16 +81,16 @@ module Onebox
81
81
  to = [to + LINES_AFTER, contents_lines_size].min # make sure expand after does not go out of bound
82
82
  end
83
83
 
84
- from = contents_lines_size if from > contents_lines_size #if "from" is out of the content top bound
84
+ from = contents_lines_size if from > contents_lines_size #if "from" is out of the content top bound
85
85
  # to = contents_lines_size if to > contents_lines_size #if "to" is out of the content top bound
86
86
  else
87
- #no expand show the one liner solely
87
+ #no expand show the one liner solely
88
88
  end
89
89
  end
90
-
90
+
91
91
  if to-from > MAX_LINES && !one_liner #if exceed the MAX_LINES limit correct unless range was produced by one_liner which it expand setting will allow exceeding the line limit
92
92
  truncated = true
93
- to = from + MAX_LINES-1
93
+ to = from + MAX_LINES-1
94
94
  end
95
95
 
96
96
  {:from => from, #calculated from
@@ -98,30 +98,30 @@ module Onebox
98
98
  :to => to, #calculated to
99
99
  :one_liner => one_liner, #boolean if a one-liner
100
100
  :selected_one_liner => @selected_one_liner, #if a one liner is provided we create a reference for it.
101
- :range_provided => range_provided, #boolean if range provided
101
+ :range_provided => range_provided, #boolean if range provided
102
102
  :truncated => truncated}
103
103
  end
104
104
 
105
- #minimize/compact leading indentation while preserving overall indentation
105
+ #minimize/compact leading indentation while preserving overall indentation
106
106
  def removeLeadingIndentation str
107
107
  #author Lidlanca 2014
108
108
  min_space=100
109
109
  a_lines = str.lines
110
110
  a_lines.each {|l|
111
- l = l.chomp("\n") # remove new line
111
+ l = l.chomp("\n") # remove new line
112
112
  m = l.match /^[ ]*/ # find leading spaces 0 or more
113
113
  unless m.nil? || l.size==m[0].size || m[0].size==0 # no match | only spaces in line | empty line
114
114
  m_str_length = m[0].size
115
115
  if m_str_length <= 1 # minimum space is 1 or nothing we can break we found our minimum
116
116
  min_space = m_str_length
117
117
  break #stop iteration
118
- end
118
+ end
119
119
  if m_str_length < min_space
120
120
  min_space = m_str_length
121
- end
121
+ end
122
122
  else
123
123
  next # SKIP no match or line is only spaces
124
- end
124
+ end
125
125
  }
126
126
  a_lines.each {|l|
127
127
  re = Regexp.new "^[ ]{#{min_space}}" #match the minimum spaces of the line
@@ -130,7 +130,7 @@ module Onebox
130
130
  a_lines.join
131
131
  end
132
132
 
133
- def line_number_helper(lines,start,selected)
133
+ def line_number_helper(lines,start,selected)
134
134
  #author Lidlanca 09/15/2014
135
135
  lines = removeLeadingIndentation(lines.join).lines # A little ineffeicent we could modify removeLeadingIndentation to accept array and return array, but for now it is only working with a string
136
136
  hash_builder =[]
@@ -155,11 +155,12 @@ module Onebox
155
155
  to = /\d+/.match(m[:to]) #get numeric should only match a positive interger
156
156
 
157
157
  @file = m[:file]
158
+ @lang = Onebox::FileTypeFinder.from_file_name(m[:file])
158
159
  contents = open("https://raw.github.com/#{m[:user]}/#{m[:repo]}/#{m[:sha1]}/#{m[:file]}", read_timeout: timeout).read
159
-
160
- contents_lines = contents.lines #get contents lines
160
+
161
+ contents_lines = contents.lines #get contents lines
161
162
  contents_lines_size = contents_lines.size #get number of lines
162
-
163
+
163
164
  cr = calc_range(m,contents_lines_size) #calculate the range of lines for output
164
165
  selected_one_liner = cr[:selected_one_liner] #if url is a one-liner calc_range will return it
165
166
  # puts "SELECTED LINE" + cr[:selected_one_liner].to_s
@@ -173,8 +174,8 @@ module Onebox
173
174
  if SHOW_LINE_NUMBER
174
175
  lines_result = line_number_helper(contents_lines[from-1..to-1], from, selected_one_liner) #print code with prefix line numbers in case range provided
175
176
  contents = lines_result[:output]
176
- @selected_lines_array = lines_result[:array]
177
- else
177
+ @selected_lines_array = lines_result[:array]
178
+ else
178
179
  contents = contents_lines[from-1..to-1].join()
179
180
  end
180
181
 
@@ -194,7 +195,11 @@ module Onebox
194
195
  def data
195
196
  @data ||= {title: link.sub(/^https?\:\/\/github\.com\//, ''),
196
197
  link: link,
198
+ # IMPORTANT NOTE: All of the other class variables are populated
199
+ # as *side effects* of the `raw` method! They must all appear
200
+ # AFTER the call to `raw`! Don't get bitten by this like I did!
197
201
  content: raw,
202
+ lang: @lang,
198
203
  lines: @selected_lines_array ,
199
204
  has_lines: !@selected_lines_array.nil?,
200
205
  selected_one_liner: @selected_one_liner,
@@ -1,9 +1,11 @@
1
- # This is broken, document.write is only allowed on load
2
- # See: http://stackoverflow.com/questions/9154026/jquery-dynamically-load-a-gist-embed
3
1
  module Onebox
4
2
  module Engine
5
3
  class GithubGistOnebox
6
4
  include Engine
5
+ include LayoutSupport
6
+ include JSON
7
+
8
+ MAX_FILES = 3
7
9
 
8
10
  matches_regexp Regexp.new("^http(?:s)?://gist\\.(?:(?:\\w)+\\.)?(github)\\.com(?:/)?")
9
11
 
@@ -11,20 +13,67 @@ module Onebox
11
13
  "https://api.github.com/gists/#{match[:sha]}"
12
14
  end
13
15
 
14
- def to_html
15
- "<script src=\"//gist.github.com/#{match[:sha]}.js\"></script>"
16
- end
17
-
18
16
  private
19
17
 
20
18
  def data
21
- { sha: match[:sha], title: match[:sha], link: @url }
19
+ @data ||= {
20
+ title: 'gist.github.com',
21
+ link: link,
22
+ gist_files: gist_files.take(MAX_FILES),
23
+ truncated_files?: truncated_files?
24
+ }
25
+ end
26
+
27
+ def truncated_files?
28
+ gist_files.size > MAX_FILES
29
+ end
30
+
31
+ def gist_files
32
+ return [] unless gist_api
33
+
34
+ @gist_files ||= gist_api["files"].values.map do |file_json|
35
+ GistFile.new(file_json)
36
+ end
37
+ end
38
+
39
+ def gist_api
40
+ @raw ||= raw.clone
41
+ rescue OpenURI::HTTPError
42
+ # The Gist API rate limit of 60 requests per hour was reached.
43
+ nil
22
44
  end
23
45
 
24
46
  def match
25
47
  @match ||= @url.match(%r{gist\.github\.com/([^/]+/)?(?<sha>[0-9a-f]+)})
26
48
  end
27
49
 
50
+ class GistFile
51
+ attr_reader :filename
52
+ attr_reader :language
53
+
54
+ MAX_LINES = 10
55
+
56
+ def initialize(json)
57
+ @json = json
58
+ @filename = @json["filename"]
59
+ @language = @json["language"]
60
+ end
61
+
62
+ def content
63
+ lines.take(MAX_LINES).join("\n")
64
+ end
65
+
66
+ def truncated?
67
+ lines.size > MAX_LINES
68
+ end
69
+
70
+ private
71
+
72
+ def lines
73
+ @lines ||= @json["content"].split("\n")
74
+ end
75
+ end
76
+
28
77
  end
29
78
  end
30
79
  end
@@ -5,19 +5,28 @@ module Onebox
5
5
  include LayoutSupport
6
6
  include HTML
7
7
 
8
+ DEFAULTS = {
9
+ MAX_DESCRIPTION_CHARS: 500
10
+ }
11
+
12
+
8
13
  matches_regexp Regexp.new("^http(?:s)?://play\\.(?:(?:\\w)+\\.)?(google)\\.com(?:/)?/store/apps/")
9
14
 
10
15
  private
11
16
 
12
17
  def data
13
- {
18
+ result = {
14
19
  link: link,
15
20
  title: raw.css(".document-title div").inner_text,
16
21
  developer: raw.css(".document-subtitle.primary").inner_text,
17
22
  image: raw.css(".cover-image").first["src"],
18
- description: raw.css(".text-body div").inner_text,
23
+ description: raw.css(".text-body div").inner_text[0..DEFAULTS[:MAX_DESCRIPTION_CHARS]].chop + "...",
19
24
  price: raw.css(".price.buy meta[itemprop=price]").first["content"]
20
25
  }
26
+ if result[:price].to_i <= 0 then
27
+ result[:price] = "Free"
28
+ end
29
+ result
21
30
  end
22
31
  end
23
32
  end
@@ -1,10 +1,9 @@
1
1
  module Onebox
2
2
  module Engine
3
3
  module StandardEmbed
4
-
5
4
  def raw
6
5
  return @raw if @raw
7
- response = fetch_response(url)
6
+ response = Onebox::Helpers.fetch_response(url)
8
7
  html_doc = Nokogiri::HTML(response.body)
9
8
 
10
9
  # Determine if we should use OEmbed or OpenGraph
@@ -12,7 +11,7 @@ module Onebox
12
11
  if oembed_alternate
13
12
  # If the oembed request fails, we can still try the opengraph below.
14
13
  begin
15
- @raw = Onebox::Helpers.symbolize_keys(::MultiJson.load(fetch_response(oembed_alternate['href']).body))
14
+ @raw = Onebox::Helpers.symbolize_keys(::MultiJson.load(Onebox::Helpers.fetch_response(oembed_alternate['href']).body))
16
15
  rescue Errno::ECONNREFUSED, Net::HTTPError, MultiJson::LoadError
17
16
  @raw = nil
18
17
  end
@@ -59,38 +58,6 @@ module Onebox
59
58
 
60
59
  og
61
60
  end
62
-
63
- def fetch_response(location, limit = 5, domain = nil,headers=nil)
64
- raise Net::HTTPError.new('HTTP redirect too deep', location) if limit == 0
65
-
66
- uri = URI(location)
67
- if !uri.host
68
- uri = URI("#{domain}#{location}")
69
- end
70
- http = Net::HTTP.new(uri.host, uri.port)
71
- http.open_timeout = Onebox.options.connect_timeout
72
- http.read_timeout = Onebox.options.timeout
73
- if uri.is_a?(URI::HTTPS)
74
- http.use_ssl = true
75
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
76
- end
77
-
78
- response = http.request_get(uri.request_uri,headers)
79
-
80
- cookie = response.get_fields('set-cookie')
81
- if (cookie)
82
- header = {'cookie' => cookie.join("")}
83
- end
84
- header = nil unless header.is_a? Hash
85
-
86
- case response
87
- when Net::HTTPSuccess then response
88
- when Net::HTTPRedirection then fetch_response(response['location'], limit - 1, "#{uri.scheme}://#{uri.host}",header)
89
- else
90
- response.error!
91
- end
92
- end
93
-
94
61
  end
95
62
  end
96
63
  end
@@ -0,0 +1,49 @@
1
+ module Onebox
2
+ module Engine
3
+ class YoukuOnebox
4
+ include Engine
5
+ include HTML
6
+
7
+ matches_regexp(/^(https?:\/\/)?([\da-z\.-]+)(youku.com\/)(.)+\/?$/)
8
+
9
+ # Try to get the video ID. Works for URLs of the form:
10
+ # * http://v.youku.com/v_show/id_XNjM3MzAxNzc2.html
11
+ def video_id
12
+ match = uri.path.match(/\/v_show\/id_([a-zA-Z0-9]*)(\.html)*/)
13
+ return match[1] if match && match[1]
14
+
15
+ nil
16
+ rescue
17
+ return nil
18
+ end
19
+
20
+ def to_html
21
+ "<iframe width='480' height='270' src='http://player.youku.com/embed/#{video_id}' frameborder='0' allowfullscreen></iframe>"
22
+ end
23
+
24
+ def placeholder_html
25
+ if video_id
26
+ meta_url = "http://v.youku.com/player/getPlayList/VideoIDS/#{video_id}"
27
+ response = Onebox::Helpers.fetch_response(meta_url)
28
+ meta = MultiJson::load(response.body) if response && response.body
29
+ image_src = if meta && meta['data'] && meta['data'][0] && meta['data'][0]['logo']
30
+ meta['data'][0]['logo']
31
+ else
32
+ nil
33
+ end
34
+ "<img src='#{image_src}' width='480' height='270'>"
35
+ else
36
+ to_html
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ # Note: May throw! Make sure to recue.
43
+ def uri
44
+ @_uri ||= URI(@url)
45
+ end
46
+
47
+ end
48
+ end
49
+ end