onebox 1.5.5 → 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
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