diff --git a/app/assets/images/favicons/stackexchange.png b/app/assets/images/favicons/stackexchange.png new file mode 100644 index 00000000000..91e4dbbe4b5 Binary files /dev/null and b/app/assets/images/favicons/stackexchange.png differ diff --git a/lib/oneboxer/stack_exchange_onebox.rb b/lib/oneboxer/stack_exchange_onebox.rb new file mode 100644 index 00000000000..0a1f42f7213 --- /dev/null +++ b/lib/oneboxer/stack_exchange_onebox.rb @@ -0,0 +1,46 @@ +require_dependency 'oneboxer/handlebars_onebox' + +module Oneboxer + class StackExchangeOnebox < HandlebarsOnebox + DOMAINS = [ + 'stackexchange', + 'stackoverflow', + 'superuser', + 'serverfault', + 'askubuntu' + ] + + # http://rubular.com/r/V3T0I1VTPn + REGEX = + /^http:\/\/(?:(?\w*)\.)?(?#{DOMAINS.join('|')})\.com\/(?:questions|q)\/(?\d*)/ + + matcher REGEX + favicon 'stackexchange.png' + + def translate_url + @url.match(REGEX) do |match| + site = if match[:domain] == 'stackexchange' + match[:subdomain] + else + match[:domain] + end + + ["http://api.stackexchange.com/2.1/", + "questions/#{match[:question]}", + "?site=#{site}" + ].join + end + end + + def parse(data) + result = JSON.parse(data)['items'].first + + result['creation_date'] = + Time.at(result['creation_date'].to_i).strftime("%I:%M%p - %d %b %y") + + result['tags'] = result['tags'].take(4).join(', ') + + result + end + end +end diff --git a/lib/oneboxer/templates/stack_exchange_onebox.hbrs b/lib/oneboxer/templates/stack_exchange_onebox.hbrs new file mode 100644 index 00000000000..57d5946e4e5 --- /dev/null +++ b/lib/oneboxer/templates/stack_exchange_onebox.hbrs @@ -0,0 +1,38 @@ +
+ {{#host}} + + {{/host}} + +
+ {{#owner.profile_image}} + + {{owner.display_name}} + + {{/owner.profile_image}} + +

+ {{{title}}} +

+ + + +
+ {{tags}} +
+
+
+
diff --git a/spec/components/oneboxer/stack_exchange_onebox_spec.rb b/spec/components/oneboxer/stack_exchange_onebox_spec.rb new file mode 100644 index 00000000000..3a4dbd9a74c --- /dev/null +++ b/spec/components/oneboxer/stack_exchange_onebox_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe Oneboxer::StackExchangeOnebox do + describe '#translate_url' do + let(:question) { '15622543' } + let(:api_url) { + "http://api.stackexchange.com/2.1/questions/#{question}?site=#{site}" + } + + context 'when the question is from Stack Overflow' do + let(:site) { 'stackoverflow' } + + it 'returns the correct api url for an expanded url' do + onebox = described_class.new([ + "http://#{site}.com/", + "questions/#{question}/discourse-ruby-2-0-rails-4" + ].join) + + expect(onebox.translate_url).to eq api_url + end + + it 'returns the correct api url for a share url' do + onebox = described_class.new("http://#{site}.com/q/#{question}") + + expect(onebox.translate_url).to eq api_url + end + end + + context 'when the question is from Super User' do + let(:site) { 'superuser' } + + it 'returns the correct api url' do + onebox = described_class.new("http://#{site}.com/q/#{question}") + + expect(onebox.translate_url).to eq api_url + end + end + + context 'when the question is from a Stack Exchange subdomain' do + let(:site) { 'gamedev' } + + it 'returns the correct api url' do + onebox = described_class.new([ + "http://#{site}.stackexchange.com/", + "questions/#{question}/how-to-prevent-the-too-awesome-to-use-syndrome" + ].join) + + expect(onebox.translate_url).to eq api_url + end + end + end +end