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