onebox 1.8.22 → 1.8.23
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 +4 -4
- data/.rubocop.yml +98 -16
- data/.travis.yml +5 -1
- data/CHANGELOG.md +6 -0
- data/Guardfile +3 -5
- data/README.md +7 -0
- data/Rakefile +1 -1
- data/lib/onebox/engine.rb +2 -3
- data/lib/onebox/engine/amazon_onebox.rb +5 -3
- data/lib/onebox/engine/douban_onebox.rb +1 -1
- data/lib/onebox/engine/github_blob_onebox.rb +68 -70
- data/lib/onebox/engine/github_issue_onebox.rb +16 -17
- data/lib/onebox/engine/google_maps_onebox.rb +2 -2
- data/lib/onebox/engine/google_play_app_onebox.rb +2 -3
- data/lib/onebox/engine/html.rb +1 -1
- data/lib/onebox/engine/pdf_onebox.rb +0 -1
- data/lib/onebox/engine/pubmed_onebox.rb +15 -15
- data/lib/onebox/engine/stack_exchange_onebox.rb +2 -2
- data/lib/onebox/engine/standard_embed.rb +1 -1
- data/lib/onebox/engine/twitch_clips_onebox.rb +1 -1
- data/lib/onebox/engine/twitch_video_onebox.rb +2 -1
- data/lib/onebox/engine/twitter_status_onebox.rb +4 -4
- data/lib/onebox/engine/wechat_mp_onebox.rb +4 -4
- data/lib/onebox/engine/whitelisted_generic_onebox.rb +1 -1
- data/lib/onebox/engine/wikipedia_onebox.rb +7 -7
- data/lib/onebox/engine/youtube_onebox.rb +1 -1
- data/lib/onebox/file_type_finder.rb +2 -2
- data/lib/onebox/helpers.rb +14 -14
- data/lib/onebox/sanitize_config.rb +1 -1
- data/lib/onebox/version.rb +1 -1
- data/onebox.gemspec +4 -0
- data/spec/lib/onebox/engine/amazon_onebox_spec.rb +0 -1
- data/spec/lib/onebox/engine/google_maps_onebox_spec.rb +1 -1
- data/spec/lib/onebox/engine/pdf_onebox_spec.rb +2 -2
- data/spec/lib/onebox/engine/pubmed_onebox_spec.rb +0 -1
- data/spec/lib/onebox/engine/stack_exchange_onebox_spec.rb +3 -3
- data/spec/lib/onebox/engine/twitter_status_onebox_spec.rb +1 -1
- data/spec/lib/onebox/engine/wechat_mp_onebox_spec.rb +3 -3
- data/spec/lib/onebox/helpers_spec.rb +8 -8
- data/spec/lib/onebox/layout_spec.rb +2 -2
- data/templates/stackexchange.mustache +1 -1
- data/templates/twitterstatus.mustache +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 584d1054d0ca1dd735a214cebe2b08427bdf3d1a
|
4
|
+
data.tar.gz: 5b070e05e93e822320f5450a70cc993d8f7bc9e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b7537379a2d5119196364a192d211dc308f7656f4e782bce43f39a73af582a57d96a368bd3056dc6d5ab56d4960d107c9073bfe0a35dc0125801a8a00769a97
|
7
|
+
data.tar.gz: af5cc488f634add8fa6af284068035f30f14c7d85f0983744cc6617e6b238f2ce9b4c8c91d424da73e6aa33cd8dcd30191857eaef9e260b1b9ab8b6a1ec1e10b
|
data/.rubocop.yml
CHANGED
@@ -1,30 +1,112 @@
|
|
1
1
|
AllCops:
|
2
|
-
|
2
|
+
TargetRubyVersion: 2.2
|
3
|
+
DisabledByDefault: true
|
3
4
|
Includes:
|
4
5
|
- '**/*.gemspec'
|
5
6
|
- '**/Rakefile'
|
6
7
|
Excludes: []
|
7
8
|
|
8
|
-
# Prefer ' strings when you don't need string interpolation or special symbols.
|
9
|
-
StringLiterals:
|
10
|
-
Enabled: false
|
11
9
|
|
12
|
-
|
10
|
+
# Prefer &&/|| over and/or.
|
11
|
+
Style/AndOr:
|
13
12
|
Enabled: true
|
14
|
-
Max: 180
|
15
13
|
|
16
|
-
#
|
17
|
-
|
14
|
+
# Do not use braces for hash literals when they are the last argument of a
|
15
|
+
# method call.
|
16
|
+
Style/BracesAroundHashParameters:
|
18
17
|
Enabled: true
|
19
|
-
CountComments: false # count full line comments?
|
20
|
-
Max: 10
|
21
18
|
|
22
|
-
#
|
23
|
-
|
24
|
-
Enabled:
|
19
|
+
# Align `when` with `case`.
|
20
|
+
Layout/CaseIndentation:
|
21
|
+
Enabled: true
|
25
22
|
|
26
|
-
|
27
|
-
|
23
|
+
# Align comments with method definitions.
|
24
|
+
Layout/CommentIndentation:
|
25
|
+
Enabled: true
|
26
|
+
|
27
|
+
# No extra empty lines.
|
28
|
+
Layout/EmptyLines:
|
29
|
+
Enabled: true
|
30
|
+
|
31
|
+
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
32
|
+
Style/HashSyntax:
|
33
|
+
Enabled: true
|
34
|
+
|
35
|
+
# Two spaces, no tabs (for indentation).
|
36
|
+
Layout/IndentationWidth:
|
37
|
+
Enabled: true
|
38
|
+
|
39
|
+
Layout/SpaceAfterColon:
|
40
|
+
Enabled: true
|
41
|
+
|
42
|
+
Layout/SpaceAfterComma:
|
43
|
+
Enabled: true
|
44
|
+
|
45
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
46
|
+
Enabled: true
|
47
|
+
|
48
|
+
Layout/SpaceAroundKeyword:
|
49
|
+
Enabled: true
|
50
|
+
|
51
|
+
Layout/SpaceAroundOperators:
|
52
|
+
Enabled: true
|
53
|
+
|
54
|
+
Layout/SpaceBeforeFirstArg:
|
55
|
+
Enabled: true
|
56
|
+
|
57
|
+
# Defining a method with parameters needs parentheses.
|
58
|
+
Style/MethodDefParentheses:
|
59
|
+
Enabled: true
|
60
|
+
|
61
|
+
# Use `foo {}` not `foo{}`.
|
62
|
+
Layout/SpaceBeforeBlockBraces:
|
63
|
+
Enabled: true
|
64
|
+
|
65
|
+
# Use `foo { bar }` not `foo {bar}`.
|
66
|
+
Layout/SpaceInsideBlockBraces:
|
67
|
+
Enabled: true
|
68
|
+
|
69
|
+
# Use `{ a: 1 }` not `{a:1}`.
|
70
|
+
Layout/SpaceInsideHashLiteralBraces:
|
71
|
+
Enabled: true
|
72
|
+
|
73
|
+
Layout/SpaceInsideParens:
|
74
|
+
Enabled: true
|
75
|
+
|
76
|
+
# Detect hard tabs, no hard tabs.
|
77
|
+
Layout/Tab:
|
78
|
+
Enabled: true
|
79
|
+
|
80
|
+
# Blank lines should not have any spaces.
|
81
|
+
Layout/TrailingBlankLines:
|
82
|
+
Enabled: true
|
83
|
+
|
84
|
+
# No trailing whitespace.
|
85
|
+
Layout/TrailingWhitespace:
|
86
|
+
Enabled: true
|
87
|
+
|
88
|
+
Lint/Debugger:
|
89
|
+
Enabled: true
|
90
|
+
|
91
|
+
Lint/BlockAlignment:
|
92
|
+
Enabled: true
|
93
|
+
|
94
|
+
# Align `end` with the matching keyword or starting expression except for
|
95
|
+
# assignments, where it should be aligned with the LHS.
|
96
|
+
Lint/EndAlignment:
|
97
|
+
Enabled: true
|
98
|
+
EnforcedStyleAlignWith: variable
|
99
|
+
|
100
|
+
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
|
101
|
+
Lint/RequireParentheses:
|
102
|
+
Enabled: true
|
103
|
+
|
104
|
+
Layout/MultilineMethodCallIndentation:
|
105
|
+
Enabled: true
|
106
|
+
EnforcedStyle: indented
|
107
|
+
|
108
|
+
Layout/AlignHash:
|
109
|
+
Enabled: true
|
28
110
|
|
29
|
-
|
111
|
+
Bundler/OrderedGems:
|
30
112
|
Enabled: false
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Guardfile
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
guard :rspec, cmd: 'bundle exec rspec' do
|
2
2
|
watch(%r{^spec/.+_spec\.rb$})
|
3
|
-
watch(%r{^lib/(.+)\.rb$})
|
4
|
-
watch('spec/spec_helper.rb')
|
5
|
-
|
6
|
-
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
3
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
4
|
+
watch('spec/spec_helper.rb') { "spec" }
|
5
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
7
6
|
end
|
8
|
-
|
data/README.md
CHANGED
@@ -71,6 +71,13 @@ preview = Onebox.preview(url)
|
|
71
71
|
"#{preview}" == preview.to_s #=> true
|
72
72
|
```
|
73
73
|
|
74
|
+
Ruby Support
|
75
|
+
------------
|
76
|
+
|
77
|
+
The onebox library is supported on all "officially" supported versions of Ruby.
|
78
|
+
|
79
|
+
This means you must be on Ruby 2.2 or above for it to work.
|
80
|
+
|
74
81
|
Development Preview Interface
|
75
82
|
-----------------------------
|
76
83
|
|
data/Rakefile
CHANGED
data/lib/onebox/engine.rb
CHANGED
@@ -26,7 +26,6 @@ module Onebox
|
|
26
26
|
@options
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
29
|
def initialize(link, cache = nil, timeout = nil)
|
31
30
|
@options = DEFAULT
|
32
31
|
class_name = self.class.name.split("::").last.to_s
|
@@ -82,13 +81,13 @@ module Onebox
|
|
82
81
|
end
|
83
82
|
|
84
83
|
def link
|
85
|
-
@url.gsub(/['\"&<>]/,
|
84
|
+
@url.gsub(/['\"&<>]/,
|
86
85
|
"'" => ''',
|
87
86
|
'&' => '&',
|
88
87
|
'"' => '"',
|
89
88
|
'<' => '<',
|
90
89
|
'>' => '>',
|
91
|
-
|
90
|
+
)
|
92
91
|
end
|
93
92
|
|
94
93
|
def always_https?
|
@@ -23,7 +23,10 @@ module Onebox
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def http_params
|
26
|
-
{
|
26
|
+
{
|
27
|
+
'User-Agent' =>
|
28
|
+
'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A405 Safari/7534.48.3'
|
29
|
+
}
|
27
30
|
end
|
28
31
|
|
29
32
|
private
|
@@ -61,7 +64,6 @@ module Onebox
|
|
61
64
|
result[:by_info] = raw.at("#by-line")
|
62
65
|
result[:by_info] = Onebox::Helpers.clean(result[:by_info].inner_html) if result[:by_info]
|
63
66
|
|
64
|
-
|
65
67
|
# get item price (Amazon markup is inconsistent, deal with it)
|
66
68
|
result[:price] =
|
67
69
|
if raw.css("#priceblock_ourprice .restOfPrice")[0] && raw.css("#priceblock_ourprice .restOfPrice")[0].inner_text
|
@@ -73,7 +75,7 @@ module Onebox
|
|
73
75
|
end
|
74
76
|
|
75
77
|
summary = raw.at("#productDescription")
|
76
|
-
result[:description] = og[:description] || summary.inner_text
|
78
|
+
result[:description] = og[:description] || (summary && summary.inner_text)
|
77
79
|
result
|
78
80
|
end
|
79
81
|
end
|
@@ -12,7 +12,7 @@ module Onebox
|
|
12
12
|
def data
|
13
13
|
{
|
14
14
|
link: link,
|
15
|
-
title: raw.css('title').text.gsub("\n",'').strip(),
|
15
|
+
title: raw.css('title').text.gsub("\n", '').strip(),
|
16
16
|
image: raw.css('img[rel*="v:"]').first['src'],
|
17
17
|
description: raw.css('meta[name=description]').first['content'],
|
18
18
|
}
|
@@ -9,18 +9,17 @@ module Onebox
|
|
9
9
|
EXPAND_NONE = 0b0
|
10
10
|
|
11
11
|
DEFAULTS = {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
EXPAND_ONE_LINER: EXPAND_AFTER | EXPAND_BEFORE, #set how to expand a one liner. user EXPAND_NONE to disable expand
|
13
|
+
LINES_BEFORE: 10,
|
14
|
+
LINES_AFTER: 10,
|
15
|
+
SHOW_LINE_NUMBER: true,
|
16
|
+
MAX_LINES: 20,
|
17
|
+
MAX_CHARS: 5000
|
18
18
|
}
|
19
19
|
|
20
20
|
matches_regexp(/^https?:\/\/(www\.)?github\.com.*\/blob\//)
|
21
21
|
always_https
|
22
22
|
|
23
|
-
|
24
23
|
def initialize(link, cache = nil, timeout = nil)
|
25
24
|
super link, cache , timeout
|
26
25
|
#merge engine options from global Onebox.options interface
|
@@ -31,20 +30,20 @@ module Onebox
|
|
31
30
|
|
32
31
|
# Define constant after merging options set in Onebox.options
|
33
32
|
# We can define constant automatically.
|
34
|
-
options.each_pair
|
33
|
+
options.each_pair do |constant_name, value|
|
35
34
|
constant_name_u = constant_name.to_s.upcase
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
if constant_name_u == constant_name.to_s
|
36
|
+
#define a constant if not already defined
|
37
|
+
self.class.const_set constant_name_u.to_sym , options[constant_name_u.to_sym] unless self.class.const_defined? constant_name_u.to_sym
|
38
|
+
end
|
39
|
+
end
|
41
40
|
end
|
42
41
|
|
43
42
|
private
|
44
|
-
@selected_lines_array
|
43
|
+
@selected_lines_array = nil
|
45
44
|
@selected_one_liner = 0
|
46
|
-
|
47
|
-
|
45
|
+
|
46
|
+
def calc_range(m, contents_lines_size)
|
48
47
|
truncated = false
|
49
48
|
from = /\d+/.match(m[:from]) #get numeric should only match a positive interger
|
50
49
|
to = /\d+/.match(m[:to]) #get numeric should only match a positive interger
|
@@ -66,7 +65,7 @@ module Onebox
|
|
66
65
|
#we can technically return here
|
67
66
|
end
|
68
67
|
|
69
|
-
from, to = [from,to].sort #enforce valid range. [from < to]
|
68
|
+
from, to = [from, to].sort #enforce valid range. [from < to]
|
70
69
|
from = 1 if from > contents_lines_size #if "from" out of TOP bound set to 1st line
|
71
70
|
to = contents_lines_size if to > contents_lines_size #if "to" is out of TOP bound set to last line.
|
72
71
|
|
@@ -88,30 +87,31 @@ module Onebox
|
|
88
87
|
end
|
89
88
|
end
|
90
89
|
|
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
|
90
|
+
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
91
|
truncated = true
|
93
|
-
to = from + MAX_LINES-1
|
92
|
+
to = from + MAX_LINES - 1
|
94
93
|
end
|
95
94
|
|
96
|
-
{
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
95
|
+
{
|
96
|
+
from: from, #calculated from
|
97
|
+
from_minus_one: from - 1, #used for getting currect ol>li numbering with css used in template
|
98
|
+
to: to, #calculated to
|
99
|
+
one_liner: one_liner, #boolean if a one-liner
|
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
|
102
|
+
truncated: truncated
|
103
|
+
}
|
103
104
|
end
|
104
105
|
|
105
106
|
#minimize/compact leading indentation while preserving overall indentation
|
106
|
-
def removeLeadingIndentation
|
107
|
-
|
108
|
-
min_space=100
|
107
|
+
def removeLeadingIndentation(str)
|
108
|
+
min_space = 100
|
109
109
|
a_lines = str.lines
|
110
|
-
a_lines.each
|
110
|
+
a_lines.each do |l|
|
111
111
|
l = l.chomp("\n") # remove new line
|
112
|
-
m = l.match
|
113
|
-
unless m.nil? || l.size==m[0].size || m[0].size==0 # no match | only spaces in line | empty line
|
114
|
-
m_str_length
|
112
|
+
m = l.match(/^[ ]*/) # find leading spaces 0 or more
|
113
|
+
unless m.nil? || l.size == m[0].size || m[0].size == 0 # no match | only spaces in line | empty line
|
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
|
@@ -122,32 +122,29 @@ module Onebox
|
|
122
122
|
else
|
123
123
|
next # SKIP no match or line is only spaces
|
124
124
|
end
|
125
|
-
|
126
|
-
a_lines.each
|
125
|
+
end
|
126
|
+
a_lines.each do |l|
|
127
127
|
re = Regexp.new "^[ ]{#{min_space}}" #match the minimum spaces of the line
|
128
128
|
l.gsub!(re, "")
|
129
|
-
|
129
|
+
end
|
130
130
|
a_lines.join
|
131
131
|
end
|
132
132
|
|
133
|
-
def line_number_helper(lines,start,selected)
|
134
|
-
#author Lidlanca 09/15/2014
|
133
|
+
def line_number_helper(lines, start, selected)
|
135
134
|
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
|
-
hash_builder =[]
|
135
|
+
hash_builder = []
|
137
136
|
output_builder = []
|
138
|
-
lines.map.with_index { |line,i|
|
139
|
-
lnum = (i.to_i+start)
|
140
|
-
hash_builder.push(
|
137
|
+
lines.map.with_index { |line, i|
|
138
|
+
lnum = (i.to_i + start)
|
139
|
+
hash_builder.push(line_number: lnum, data: line.gsub("\n", ""), selected: (selected == lnum) ? true : false)
|
141
140
|
output_builder.push "#{lnum}: #{line}"
|
142
141
|
}
|
143
|
-
{:
|
142
|
+
{ output: output_builder.join(), array: hash_builder }
|
144
143
|
end
|
145
144
|
|
146
|
-
|
147
145
|
def raw
|
148
|
-
options_id = self.class.name.split("::").last.to_s #get class name without module namespace
|
149
|
-
|
150
146
|
return @raw if @raw
|
147
|
+
|
151
148
|
m = @url.match(/github\.com\/(?<user>[^\/]+)\/(?<repo>[^\/]+)\/blob\/(?<sha1>[^\/]+)\/(?<file>[^#]+)(#(L(?<from>[^-]*)(-L(?<to>.*))?))?/mi)
|
152
149
|
|
153
150
|
if m
|
@@ -161,26 +158,25 @@ module Onebox
|
|
161
158
|
contents_lines = contents.lines #get contents lines
|
162
159
|
contents_lines_size = contents_lines.size #get number of lines
|
163
160
|
|
164
|
-
cr = calc_range(m,contents_lines_size) #calculate the range of lines for output
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
@cr_results = cr
|
161
|
+
cr = calc_range(m, contents_lines_size) #calculate the range of lines for output
|
162
|
+
selected_one_liner = cr[:selected_one_liner] #if url is a one-liner calc_range will return it
|
163
|
+
from = cr[:from]
|
164
|
+
to = cr[:to]
|
165
|
+
@truncated = cr[:truncated]
|
166
|
+
range_provided = cr[:range_provided]
|
167
|
+
@cr_results = cr
|
168
|
+
|
173
169
|
if range_provided #if a range provided (single line or more)
|
174
170
|
if SHOW_LINE_NUMBER
|
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
|
171
|
+
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
|
176
172
|
contents = lines_result[:output]
|
177
173
|
@selected_lines_array = lines_result[:array]
|
178
174
|
else
|
179
|
-
contents = contents_lines[from-1..to-1].join()
|
175
|
+
contents = contents_lines[(from - 1)..(to - 1)].join()
|
180
176
|
end
|
181
177
|
|
182
178
|
else
|
183
|
-
contents = contents_lines[from-1..to-1].join()
|
179
|
+
contents = contents_lines[(from - 1)..(to - 1)].join()
|
184
180
|
end
|
185
181
|
|
186
182
|
if contents.length > MAX_CHARS #truncate content chars to limits
|
@@ -193,18 +189,20 @@ module Onebox
|
|
193
189
|
end
|
194
190
|
|
195
191
|
def data
|
196
|
-
@data ||= {
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
192
|
+
@data ||= {
|
193
|
+
title: link.sub(/^https?\:\/\/github\.com\//, ''),
|
194
|
+
link: link,
|
195
|
+
# IMPORTANT NOTE: All of the other class variables are populated
|
196
|
+
# as *side effects* of the `raw` method! They must all appear
|
197
|
+
# AFTER the call to `raw`! Don't get bitten by this like I did!
|
198
|
+
content: raw,
|
199
|
+
lang: "lang-#{@lang}",
|
200
|
+
lines: @selected_lines_array ,
|
201
|
+
has_lines: !@selected_lines_array.nil?,
|
202
|
+
selected_one_liner: @selected_one_liner,
|
203
|
+
cr_results: @cr_results,
|
204
|
+
truncated: @truncated
|
205
|
+
}
|
208
206
|
end
|
209
207
|
|
210
208
|
end
|
@@ -16,33 +16,32 @@ module Onebox
|
|
16
16
|
private
|
17
17
|
|
18
18
|
def match
|
19
|
-
|
19
|
+
@match ||= @url.match(/^http(?:s)?:\/\/(?:www\.)?(?:(?:\w)+\.)?github\.com\/(?<org>.+)\/(?<repo>.+)\/(?<type>issues)\/(?<item_id>[\d]+)/)
|
20
20
|
end
|
21
21
|
|
22
22
|
def data
|
23
23
|
|
24
|
-
@raw ||= ::MultiJson.load(open(url,"Accept"=>"application/vnd.github.v3.text+json"
|
25
|
-
body_text=
|
24
|
+
@raw ||= ::MultiJson.load(open(url, "Accept" => "application/vnd.github.v3.text+json", read_timeout: timeout)) #custom Accept header so we can get body as text.
|
25
|
+
body_text = @raw["body_text"]
|
26
26
|
|
27
|
-
|
28
|
-
content_words = body_text.gsub("\n\n","\n").gsub("\n","<br>").split(" ") #one pass of removing double newline, then we change \n to <br> and later on we revert it back to \n this is a workaround to avoid losing newlines after we join it back.
|
27
|
+
content_words = body_text.gsub("\n\n", "\n").gsub("\n", "<br>").split(" ") #one pass of removing double newline, then we change \n to <br> and later on we revert it back to \n this is a workaround to avoid losing newlines after we join it back.
|
29
28
|
max_words = 20
|
30
29
|
short_content = content_words[0..max_words].join(" ")
|
31
30
|
short_content << "..." if content_words.length > max_words
|
32
31
|
|
33
32
|
ulink = URI(link)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
33
|
+
{
|
34
|
+
link: @url,
|
35
|
+
title: "Issue: " + @raw["title"],
|
36
|
+
content: short_content.gsub("<br>", "\n"),
|
37
|
+
labels: @raw["labels"],
|
38
|
+
user: @raw['user'],
|
39
|
+
created_at: @raw['created_at'].split("T")[0], #get only date for now
|
40
|
+
closed_at: (@raw['closed_at'].nil? ? "" : @raw['closed_at'].split("T")[0]),
|
41
|
+
closed_by: @raw['closed_by'],
|
42
|
+
avatar: "https://avatars1.githubusercontent.com/u/#{@raw['user']['id']}?v=2&s=96",
|
43
|
+
domain: "#{ulink.host}/#{ulink.path.split('/')[1]}/#{ulink.path.split('/')[2]}",
|
44
|
+
}
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
@@ -6,7 +6,7 @@ module Onebox
|
|
6
6
|
class << self
|
7
7
|
def ===(other)
|
8
8
|
if other.kind_of? URI
|
9
|
-
@@matchers && @@matchers.any? {|m| other.to_s =~ m[:regexp] }
|
9
|
+
@@matchers && @@matchers.any? { |m| other.to_s =~ m[:regexp] }
|
10
10
|
else
|
11
11
|
super
|
12
12
|
end
|
@@ -15,7 +15,7 @@ module Onebox
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def matches_regexp(key, regexp)
|
18
|
-
(@@matchers ||= []) << {key: key, regexp: regexp}
|
18
|
+
(@@matchers ||= []) << { key: key, regexp: regexp }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -9,7 +9,6 @@ module Onebox
|
|
9
9
|
MAX_DESCRIPTION_CHARS: 500
|
10
10
|
}
|
11
11
|
|
12
|
-
|
13
12
|
matches_regexp Regexp.new("^https?://play\\.(?:(?:\\w)+\\.)?(google)\\.com(?:/)?/store/apps/")
|
14
13
|
always_https
|
15
14
|
|
@@ -24,8 +23,8 @@ module Onebox
|
|
24
23
|
description: raw.css(".text-body div").inner_text[0..DEFAULTS[:MAX_DESCRIPTION_CHARS]].chop + "...",
|
25
24
|
price: raw.css(".price.buy meta[itemprop=price]").first["content"]
|
26
25
|
}
|
27
|
-
if result[:price] == "0"
|
28
|
-
|
26
|
+
if result[:price] == "0"
|
27
|
+
result[:price] = "Free"
|
29
28
|
end
|
30
29
|
result
|
31
30
|
end
|
data/lib/onebox/engine/html.rb
CHANGED
@@ -15,9 +15,9 @@ module Onebox
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def authors_of_xml(xml)
|
18
|
-
initials = xml.css("Initials").map{|x| x.content}
|
19
|
-
last_names = xml.css("LastName").map{|x| x.content}
|
20
|
-
author_list = (initials.zip(last_names)).map{|i,l| i + " " + l}
|
18
|
+
initials = xml.css("Initials").map { |x| x.content }
|
19
|
+
last_names = xml.css("LastName").map { |x| x.content }
|
20
|
+
author_list = (initials.zip(last_names)).map { |i, l| i + " " + l }
|
21
21
|
if author_list.length > 1 then
|
22
22
|
author_list[-2] = author_list[-2] + " and " + author_list[-1]
|
23
23
|
author_list.pop
|
@@ -26,22 +26,22 @@ module Onebox
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def date_of_xml(xml)
|
29
|
-
date_arr = (xml.css("PubDate").children).map{|x| x.content}
|
30
|
-
date_arr = date_arr.select{|s| !s.match(/^\s+$/)}
|
31
|
-
date_arr = (date_arr.map{|s| s.split}).flatten
|
29
|
+
date_arr = (xml.css("PubDate").children).map { |x| x.content }
|
30
|
+
date_arr = date_arr.select { |s| !s.match(/^\s+$/) }
|
31
|
+
date_arr = (date_arr.map { |s| s.split }).flatten
|
32
32
|
date_arr.sort.reverse.join(" ") # Reverse sort so month before year.
|
33
33
|
end
|
34
34
|
|
35
35
|
def data
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
xml = get_xml()
|
37
|
+
{
|
38
|
+
title: xml.css("ArticleTitle").text,
|
39
|
+
authors: authors_of_xml(xml),
|
40
|
+
journal: xml.css("Title").text,
|
41
|
+
abstract: xml.css("AbstractText").text,
|
42
|
+
date: date_of_xml(xml),
|
43
|
+
link: @url,
|
44
|
+
pmid: match[:pmid]
|
45
45
|
}
|
46
46
|
end
|
47
47
|
|
@@ -7,10 +7,10 @@ module Onebox
|
|
7
7
|
|
8
8
|
def self.domains
|
9
9
|
%w(stackexchange.com stackoverflow.com superuser.com serverfault.com askubuntu.com stackapps.com mathoverflow.net)
|
10
|
-
|
10
|
+
.map { |domain| Regexp.escape(domain) }
|
11
11
|
end
|
12
12
|
|
13
|
-
matches_regexp
|
13
|
+
matches_regexp(/^https?:\/\/(?:(?:(?<subsubdomain>\w*)\.)?(?<subdomain>\w*)\.)?(?<domain>#{domains.join('|')})\/((?:questions|q)\/(?<question_id>\d*)(\/.*\/(?<answer_id1>\d*))?|(a\/(?<answer_id2>\d*)))/)
|
14
14
|
|
15
15
|
def always_https?
|
16
16
|
uri.host.split('.').length <= 3
|
@@ -119,7 +119,7 @@ module Onebox
|
|
119
119
|
html_doc.css('meta').each do |m|
|
120
120
|
if (m["property"] && m["property"][/^twitter:(.+)$/i]) || (m["name"] && m["name"][/^twitter:(.+)$/i])
|
121
121
|
value = (m["content"] || m["value"]).to_s
|
122
|
-
twitter[$1.tr('-:','_').to_sym] ||= value unless Onebox::Helpers::blank?(value)
|
122
|
+
twitter[$1.tr('-:' , '_').to_sym] ||= value unless Onebox::Helpers::blank?(value)
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -3,7 +3,7 @@ require_relative '../mixins/twitch_onebox'
|
|
3
3
|
class Onebox::Engine::TwitchClipsOnebox
|
4
4
|
|
5
5
|
def self.twitch_regexp
|
6
|
-
|
6
|
+
/^https?:\/\/clips\.twitch\.tv\/([a-zA-Z0-9_]+\/?[^#\?\/]+)/
|
7
7
|
end
|
8
8
|
include Onebox::Mixins::TwitchOnebox
|
9
9
|
|
@@ -3,8 +3,9 @@ require_relative '../mixins/twitch_onebox'
|
|
3
3
|
class Onebox::Engine::TwitchVideoOnebox
|
4
4
|
|
5
5
|
def self.twitch_regexp
|
6
|
-
|
6
|
+
/^https?:\/\/(?:www\.)?twitch\.tv\/videos\/([0-9]+)/
|
7
7
|
end
|
8
|
+
|
8
9
|
include Onebox::Mixins::TwitchOnebox
|
9
10
|
|
10
11
|
def query_params
|
@@ -5,7 +5,7 @@ module Onebox
|
|
5
5
|
include LayoutSupport
|
6
6
|
include HTML
|
7
7
|
|
8
|
-
matches_regexp
|
8
|
+
matches_regexp(/^https?:\/\/(mobile\.|www\.)?twitter\.com\/.+?\/status(es)?\/\d+(\/(video|photo)\/\d?+)?+\/?$/)
|
9
9
|
always_https
|
10
10
|
|
11
11
|
private
|
@@ -84,9 +84,9 @@ module Onebox
|
|
84
84
|
|
85
85
|
def avatar
|
86
86
|
if twitter_api_credentials_present?
|
87
|
-
access(:user, :profile_image_url_https)
|
88
|
-
|
89
|
-
twitter_data[:image]
|
87
|
+
access(:user, :profile_image_url_https).sub('normal', '400x400')
|
88
|
+
elsif twitter_data[:image]
|
89
|
+
twitter_data[:image]
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -22,19 +22,19 @@ module Onebox
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def extract_script_value(var_name)
|
25
|
-
if (script_elem = raw.css("script").select{|script| script.inner_text.include? "var #{var_name} = "}) && script_elem.any?
|
25
|
+
if (script_elem = raw.css("script").select { |script| script.inner_text.include? "var #{var_name} = " }) && script_elem.any?
|
26
26
|
e = Nokogiri::HTML(script_elem[0].inner_text.match(/var\s+#{Regexp.quote(var_name)}\s+=\s+"(.*?)";/)[1])
|
27
|
-
return CGI::unescapeHTML(e.text.scan(/(?:\\x([a-f0-9]{2}))|(.)/i).map { |x| x[0] ? [x[0].to_i(16)].pack('U'): x[1] }.join)
|
27
|
+
return CGI::unescapeHTML(e.text.scan(/(?:\\x([a-f0-9]{2}))|(.)/i).map { |x| x[0] ? [x[0].to_i(16)].pack('U') : x[1] }.join)
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
# TODO need to handle hotlink protection from wechat
|
32
32
|
def image
|
33
33
|
if banner_image = extract_script_value("msg_cdn_url")
|
34
34
|
return banner_image
|
35
35
|
end
|
36
36
|
|
37
|
-
if (main_image = raw.css("img").select{|img| not img['class']}) && main_image.any?
|
37
|
+
if (main_image = raw.css("img").select { |img| not img['class'] }) && main_image.any?
|
38
38
|
attributes = main_image.first.attributes
|
39
39
|
|
40
40
|
return attributes["data-src"].to_s if attributes["data-src"]
|
@@ -165,7 +165,7 @@ module Onebox
|
|
165
165
|
end
|
166
166
|
|
167
167
|
def self.host_matches(uri, list)
|
168
|
-
!!list.find {|h| %r((^|\.)#{Regexp.escape(h)}$).match(uri.host) }
|
168
|
+
!!list.find { |h| %r((^|\.)#{Regexp.escape(h)}$).match(uri.host) }
|
169
169
|
end
|
170
170
|
|
171
171
|
def self.probable_discourse(uri)
|
@@ -17,8 +17,8 @@ module Onebox
|
|
17
17
|
# Detect section Hash in the url and retrive the related paragraphs. if no hash provided the first few paragraphs will be used
|
18
18
|
# Author Lidlanca
|
19
19
|
# Date 9/8/2014
|
20
|
-
if (
|
21
|
-
m_url_hash_name= m_url_hash[1]
|
20
|
+
if (m_url_hash = @url.match(/#([^\/?]+)/)) #extract url hash
|
21
|
+
m_url_hash_name = m_url_hash[1]
|
22
22
|
end
|
23
23
|
|
24
24
|
unless m_url_hash.nil?
|
@@ -35,7 +35,7 @@ module Onebox
|
|
35
35
|
# div tag is commonly used as an assets wraper in an article section. often as the first element holding an image.
|
36
36
|
# 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)
|
37
37
|
first_p_found = nil
|
38
|
-
while (
|
38
|
+
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
|
39
39
|
cur_element = next_sibling
|
40
40
|
if (cur_element.name == "p" || cur_element.name == "ul") #we treat a list as we detect a p to avoid showing
|
41
41
|
first_p_found = true
|
@@ -53,11 +53,11 @@ module Onebox
|
|
53
53
|
break if cnt >= paras.size
|
54
54
|
text << " " unless cnt == 0
|
55
55
|
|
56
|
-
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
|
57
|
-
li_index=1
|
56
|
+
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
|
57
|
+
li_index = 1
|
58
58
|
list_items = []
|
59
|
-
paras[cnt].children.css("li").each {|li| list_items.push "#{li_index}." + li.inner_text ; li_index+=1}
|
60
|
-
paragraph =
|
59
|
+
paras[cnt].children.css("li").each { |li| list_items.push "#{li_index}." + li.inner_text ; li_index += 1 }
|
60
|
+
paragraph = (list_items.join " |\n ")[0..Onebox::LayoutSupport.max_text]
|
61
61
|
else
|
62
62
|
paragraph = paras[cnt].inner_text[0..Onebox::LayoutSupport.max_text]
|
63
63
|
end
|
@@ -52,14 +52,14 @@ module Onebox
|
|
52
52
|
# First check against the known lists of "special" files and extensions.
|
53
53
|
return @extensionless_files[lower_name] if @extensionless_files.has_key?(lower_name)
|
54
54
|
|
55
|
-
@long_file_types.each { |extension,type|
|
55
|
+
@long_file_types.each { |extension, type|
|
56
56
|
return type if lower_name.end_with?(extension)
|
57
57
|
}
|
58
58
|
|
59
59
|
# Otherwise, just split on the last ".",
|
60
60
|
# but add one so we don't return the "." itself.
|
61
61
|
dot_spot = lower_name.rindex(".")
|
62
|
-
return lower_name[(dot_spot+1)..-1] if dot_spot
|
62
|
+
return lower_name[(dot_spot + 1)..-1] if dot_spot
|
63
63
|
|
64
64
|
# If we couldn't figure it out from the name,
|
65
65
|
# let the highlighter figure it out from the content.
|
data/lib/onebox/helpers.rb
CHANGED
@@ -6,12 +6,12 @@ module Onebox
|
|
6
6
|
def self.symbolize_keys(hash)
|
7
7
|
return {} if hash.nil?
|
8
8
|
|
9
|
-
hash.inject({})
|
9
|
+
hash.inject({}) do |result, (key, value)|
|
10
10
|
new_key = key.is_a?(String) ? key.to_sym : key
|
11
11
|
new_value = value.is_a?(Hash) ? symbolize_keys(value) : value
|
12
12
|
result[new_key] = new_value
|
13
13
|
result
|
14
|
-
|
14
|
+
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.clean(html)
|
@@ -26,7 +26,7 @@ module Onebox
|
|
26
26
|
doc.css('meta').each do |m|
|
27
27
|
if (m["property"] && m["property"][/^og:(.+)$/i]) || (m["name"] && m["name"][/^og:(.+)$/i])
|
28
28
|
value = (m["content"] || m["value"]).to_s
|
29
|
-
og[$1.tr('-:','_').to_sym] ||= value unless Onebox::Helpers::blank?(value)
|
29
|
+
og[$1.tr('-:', '_').to_sym] ||= value unless Onebox::Helpers::blank?(value)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -39,7 +39,7 @@ module Onebox
|
|
39
39
|
og
|
40
40
|
end
|
41
41
|
|
42
|
-
def self.fetch_response(location, limit=nil, domain=nil, headers=nil)
|
42
|
+
def self.fetch_response(location, limit = nil, domain = nil, headers = nil)
|
43
43
|
|
44
44
|
limit ||= 5
|
45
45
|
limit = Onebox.options.redirect_limit if limit > Onebox.options.redirect_limit
|
@@ -123,18 +123,18 @@ module Onebox
|
|
123
123
|
conv = [ 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB' ];
|
124
124
|
scale = 1024;
|
125
125
|
|
126
|
-
ndx=1
|
127
|
-
if(
|
128
|
-
return "#{(size)} #{conv[ndx-1]}"
|
126
|
+
ndx = 1
|
127
|
+
if (size < 2 * (scale**ndx)) then
|
128
|
+
return "#{(size)} #{conv[ndx - 1]}"
|
129
129
|
end
|
130
|
-
size=size.to_f
|
131
|
-
[2,3,4,5,6,7].each do |i|
|
132
|
-
if (size < 2*(scale**i)) then
|
133
|
-
return "#{'%.2f' % (size/(scale**(i-1)))} #{conv[i-1]}"
|
130
|
+
size = size.to_f
|
131
|
+
[2, 3, 4, 5, 6, 7].each do |i|
|
132
|
+
if (size < 2 * (scale**i)) then
|
133
|
+
return "#{'%.2f' % (size / (scale**(i - 1)))} #{conv[i - 1]}"
|
134
134
|
end
|
135
135
|
end
|
136
|
-
ndx=7
|
137
|
-
return "#{'%.2f' % (size/(scale**(ndx-1)))} #{conv[ndx-1]}"
|
136
|
+
ndx = 7
|
137
|
+
return "#{'%.2f' % (size / (scale**(ndx - 1)))} #{conv[ndx - 1]}"
|
138
138
|
end
|
139
139
|
|
140
140
|
def self.click_to_scroll_div(width = 690, height = 400)
|
@@ -150,7 +150,7 @@ module Onebox
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def self.truncate(string, length = 50)
|
153
|
-
string.size > length ? string[0...(string.rindex(" ", length)||length)] + "..." : string
|
153
|
+
string.size > length ? string[0...(string.rindex(" ", length) || length)] + "..." : string
|
154
154
|
end
|
155
155
|
|
156
156
|
def self.title_attr(meta)
|
data/lib/onebox/version.rb
CHANGED
data/onebox.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
1
3
|
# coding: utf-8
|
2
4
|
lib = File.expand_path('../lib', __FILE__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
@@ -40,4 +42,6 @@ Gem::Specification.new do |spec|
|
|
40
42
|
spec.add_development_dependency 'sinatra-contrib', '~> 1.4'
|
41
43
|
spec.add_development_dependency 'haml', '~> 4.0'
|
42
44
|
spec.add_development_dependency 'listen', '~> 2.10.0'
|
45
|
+
|
46
|
+
spec.required_ruby_version = '>=2.2.0'
|
43
47
|
end
|
@@ -56,7 +56,7 @@ describe Onebox::Engine::GoogleMapsOnebox do
|
|
56
56
|
end
|
57
57
|
|
58
58
|
let(:data) { Onebox::Helpers.symbolize_keys(subject.send(:data)) }
|
59
|
-
let(:link) {|example| URLS[example.metadata[:urltype] || :short][:test] }
|
59
|
+
let(:link) { |example| URLS[example.metadata[:urltype] || :short][:test] }
|
60
60
|
|
61
61
|
include_context "an engine", urltype: :short
|
62
62
|
|
@@ -8,8 +8,8 @@ describe Onebox::Engine::PdfOnebox do
|
|
8
8
|
let(:no_filesize_html) { described_class.new(no_content_length_link).to_html }
|
9
9
|
|
10
10
|
before do
|
11
|
-
FakeWeb.register_uri(:head, link, :
|
12
|
-
FakeWeb.register_uri(:head, no_content_length_link, :
|
11
|
+
FakeWeb.register_uri(:head, link, content_length: "335562")
|
12
|
+
FakeWeb.register_uri(:head, no_content_length_link, content_length: nil)
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "#to_html" do
|
@@ -39,7 +39,7 @@ describe Onebox::Engine::StackExchangeOnebox do
|
|
39
39
|
|
40
40
|
{
|
41
41
|
'long URL' => 'http://stackoverflow.com/questions/17992553/concept-behind-these-four-lines-of-tricky-c-code',
|
42
|
-
'short URL'=> 'http://stackoverflow.com/q/17992553'
|
42
|
+
'short URL' => 'http://stackoverflow.com/q/17992553'
|
43
43
|
}.each do |name, url|
|
44
44
|
describe "question with #{name}" do
|
45
45
|
before(:all) do
|
@@ -68,7 +68,7 @@ describe Onebox::Engine::StackExchangeOnebox do
|
|
68
68
|
|
69
69
|
{
|
70
70
|
'long URL' => 'http://stackoverflow.com/questions/17992553/concept-behind-these-four-lines-of-tricky-c-code/17992906#17992906',
|
71
|
-
'short URL'=> 'http://stackoverflow.com/a/17992906'
|
71
|
+
'short URL' => 'http://stackoverflow.com/a/17992906'
|
72
72
|
}.each do |name, url|
|
73
73
|
describe "answer with #{name}" do
|
74
74
|
before(:all) do
|
@@ -94,4 +94,4 @@ describe Onebox::Engine::StackExchangeOnebox do
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
97
|
-
end
|
97
|
+
end
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Onebox::Engine::WechatMpOnebox do
|
4
4
|
|
5
|
-
let(:link) {"https://mp.weixin.qq.com/s?__biz=MjM5NjM4MDAxMg==&mid=2655075181&idx=1&sn=7c58f17de2c687f4763f17359ecc6e72&chksm=bd5fb76e8a283e7856cae30a74e905a18d9511e81c047b6e12390889de15976fb2c297b04106#rd"}
|
5
|
+
let(:link) { "https://mp.weixin.qq.com/s?__biz=MjM5NjM4MDAxMg==&mid=2655075181&idx=1&sn=7c58f17de2c687f4763f17359ecc6e72&chksm=bd5fb76e8a283e7856cae30a74e905a18d9511e81c047b6e12390889de15976fb2c297b04106#rd" }
|
6
6
|
let(:html) { described_class.new(link).to_html }
|
7
7
|
|
8
8
|
describe "#to_html" do
|
@@ -13,11 +13,11 @@ describe Onebox::Engine::WechatMpOnebox do
|
|
13
13
|
it "has the article's title" do
|
14
14
|
expect(html).to include("不是月光宝盒,但也能回到过去")
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "has the article's description" do
|
18
18
|
expect(html).to include("你知道吗?从今天起,公众号后台编辑文章时可以……")
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it "has the article's author" do
|
22
22
|
expect(html).to include("微信派")
|
23
23
|
end
|
@@ -8,21 +8,21 @@ RSpec.describe Onebox::Helpers do
|
|
8
8
|
it { expect(described_class.blank?(["test", "testing"])).to be(false) }
|
9
9
|
it { expect(described_class.blank?([])).to be(true) }
|
10
10
|
it { expect(described_class.blank?({})).to be(true) }
|
11
|
-
it { expect(described_class.blank?({a: 'test'})).to be(false) }
|
12
11
|
it { expect(described_class.blank?(nil)).to be(true) }
|
13
12
|
it { expect(described_class.blank?(true)).to be(false) }
|
14
13
|
it { expect(described_class.blank?(false)).to be(true) }
|
14
|
+
it { expect(described_class.blank?(a: 'test')).to be(false) }
|
15
15
|
end
|
16
16
|
|
17
17
|
describe ".truncate" do
|
18
18
|
let(:test_string) { "Chops off on spaces" }
|
19
19
|
it { expect(described_class.truncate(test_string)).to eq(test_string) }
|
20
|
-
it { expect(described_class.truncate(test_string,5)).to eq("Chops...") }
|
21
|
-
it { expect(described_class.truncate(test_string,7)).to eq("Chops...") }
|
22
|
-
it { expect(described_class.truncate(test_string,9)).to eq("Chops off...") }
|
23
|
-
it { expect(described_class.truncate(test_string,10)).to eq("Chops off...") }
|
24
|
-
it { expect(described_class.truncate(test_string,100)).to eq("Chops off on spaces") }
|
25
|
-
it { expect(described_class.truncate(" #{test_string} ",6)).to eq(" Chops...") }
|
20
|
+
it { expect(described_class.truncate(test_string, 5)).to eq("Chops...") }
|
21
|
+
it { expect(described_class.truncate(test_string, 7)).to eq("Chops...") }
|
22
|
+
it { expect(described_class.truncate(test_string, 9)).to eq("Chops off...") }
|
23
|
+
it { expect(described_class.truncate(test_string, 10)).to eq("Chops off...") }
|
24
|
+
it { expect(described_class.truncate(test_string, 100)).to eq("Chops off on spaces") }
|
25
|
+
it { expect(described_class.truncate(" #{test_string} ", 6)).to eq(" Chops...") }
|
26
26
|
end
|
27
27
|
|
28
28
|
describe "fetch_response" do
|
@@ -44,7 +44,7 @@ RSpec.describe Onebox::Helpers do
|
|
44
44
|
|
45
45
|
describe "user_agent" do
|
46
46
|
before do
|
47
|
-
fake("http://example.com/some-resource", :
|
47
|
+
fake("http://example.com/some-resource", body: 'test')
|
48
48
|
end
|
49
49
|
|
50
50
|
context "default" do
|
@@ -16,7 +16,7 @@ describe Onebox::Layout do
|
|
16
16
|
|
17
17
|
context "when template exists in directory_b" do
|
18
18
|
before(:each) do
|
19
|
-
allow_any_instance_of(described_class).to receive(:template?) { |_,path| path == "directory_b" }
|
19
|
+
allow_any_instance_of(described_class).to receive(:template?) { |_, path| path == "directory_b" }
|
20
20
|
end
|
21
21
|
|
22
22
|
it "returns directory_b" do
|
@@ -26,7 +26,7 @@ describe Onebox::Layout do
|
|
26
26
|
|
27
27
|
context "when template exists in directory_a" do
|
28
28
|
before(:each) do
|
29
|
-
allow_any_instance_of(described_class).to receive(:template?) { |_,path| path == "directory_a" }
|
29
|
+
allow_any_instance_of(described_class).to receive(:template?) { |_, path| path == "directory_a" }
|
30
30
|
end
|
31
31
|
|
32
32
|
it "returns directory_a" do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{{#owner.profile_image}}
|
2
2
|
<a href="{{owner.link}}" target="_blank">
|
3
|
-
<img alt="{{owner.display_name}}" src="{{owner.profile_image}}" class="thumbnail">
|
3
|
+
<img alt="{{owner.display_name}}" src="{{owner.profile_image}}" class="thumbnail onebox-avatar">
|
4
4
|
</a>
|
5
5
|
{{/owner.profile_image}}
|
6
6
|
<h4>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onebox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joanna Zeta
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-11-
|
13
|
+
date: 2017-11-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: multi_json
|
@@ -516,7 +516,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
516
516
|
requirements:
|
517
517
|
- - ">="
|
518
518
|
- !ruby/object:Gem::Version
|
519
|
-
version:
|
519
|
+
version: 2.2.0
|
520
520
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
521
521
|
requirements:
|
522
522
|
- - ">="
|
@@ -611,3 +611,4 @@ test_files:
|
|
611
611
|
- spec/lib/onebox_spec.rb
|
612
612
|
- spec/spec_helper.rb
|
613
613
|
- spec/support/html_spec_helper.rb
|
614
|
+
has_rdoc:
|