From 1fb0b424ed62a38120419abec93050fce6fc540a Mon Sep 17 00:00:00 2001 From: Chris Hunt <c@chrishunt.co> Date: Mon, 10 Jun 2013 09:27:13 -0700 Subject: [PATCH] Add Stack Exchange onebox --- app/assets/images/favicons/stackexchange.png | Bin 0 -> 1438 bytes lib/oneboxer/stack_exchange_onebox.rb | 46 ++++++++++++++++ .../templates/stack_exchange_onebox.hbrs | 38 +++++++++++++ .../oneboxer/stack_exchange_onebox_spec.rb | 52 ++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 app/assets/images/favicons/stackexchange.png create mode 100644 lib/oneboxer/stack_exchange_onebox.rb create mode 100644 lib/oneboxer/templates/stack_exchange_onebox.hbrs create mode 100644 spec/components/oneboxer/stack_exchange_onebox_spec.rb diff --git a/app/assets/images/favicons/stackexchange.png b/app/assets/images/favicons/stackexchange.png new file mode 100644 index 0000000000000000000000000000000000000000..91e4dbbe4b5f9d11f558519529db543ba59d1ffd GIT binary patch literal 1438 zcmV;P1!4M$P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV000CeX+uL$Nkc;* zP;zf(X>4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z<T^KrsT&8|>9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~<wJLg{8L_J?=wVD}Kh?c9aozEndlcyGxo=u9<v(!ri)T`-EEs@L3 z5-!0N_s;9#9f}Cc?UC;OPWB_edW+oAi6T$HZWSGU8TbrQ%+zbPOBBBc`}k?M2Hf); z@Y6N~0;>X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX<gx$-tTA9oOBadXir_JPm2Y^4ct-PoO&C)tI zGolvqOIK@duBk!Vu9{g<3;i;gJ6?~-DQ&xz!jvD&4!U-s8Os(*#?k2}f30SEXA#=i z1-qUX+K`{!((H5w7<t$~ygD!D1{~X6)KX%$qrgY#L_{M_7A<1csY*MfP@XcB#Jxr~ zJS8&7goVS)VKE|4(h_Xlc{z{c$ApZs7riZ_QKdV_uW-M~u~<J-*#Z0?VzcZp8)p-w zus7J7><CN2I>8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#<s%v*srlI z{B2SKJ79W>mZ8e<cESmGBON_l0n;T7>u=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-D<EBz>aCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaE<h}6h3HHql{T;m+bPBU-O|^S1 z@dOw&4<!bj2G_<^#e}PL7FpY$lcrKO$i~?8Bd2y;oaL5^csibnCrF9!i%-PI;xhub zp1k;8_$IKX1NHus6EHeD;B72SCCD@4ojP$=Mf3`Eo6yZ&eg@wTqDiZE);7u&SJ|(s zuPF(9%D6IJ)klXF%`_Fy<tR3HxV^%Qqa?nAB97=m-uu2qcHInZ?ps8M|H3=#R%lzO z6MgLv^}ib0hVV{&<};#;2lcwW;^(7C<OY#bI<VjS9qCKr-E_Cnc!2j+&nHAXA2%BR zt~VMxUn2h&(Pi^LSpac(Y#S>R0003sNkl<ZI1yv~|NlP&2s9ozz#=T7mBPrxC<qq7 zLHz&s|NYxH*XGnaIQ#)AVS%X=71!Rt%FN^q<Kv@Qh18va@}VF#OfZG4j7+XDHa`08 zkKYXMzWsq)#0c{OK27-K;9f}H{0R~mI8;CV@Q2~qhktO{OSvM9AP(FMa2YHNbj`?0 zsON>iwksH3c>LlA!?Ty)ku8L?pRKgT?*)9C;ido?)boOW{?aGR%*@h{pS@#v`s_Wj zB^d1g4FA9UefL-L)s^}$@K|7EWMn5sGsHAT&Yye?Y#=r~9o&ENHtE%?Pc=Y4F(a&G z<Yr)GPz3VX5n}&uGyZ36{&=kZ9Y~B|7)aT*B4X#?zszSxYG)t}BQhZYllvzi&Oz4< sG6?PkWK%KN|NmP(KT>-YLmVgo07mG4yve3Ke*gdg07*qoM6N<$f<ceFC;$Ke literal 0 HcmV?d00001 diff --git a/lib/oneboxer/stack_exchange_onebox.rb b/lib/oneboxer/stack_exchange_onebox.rb new file mode 100644 index 000000000..0a1f42f72 --- /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:\/\/(?:(?<subdomain>\w*)\.)?(?<domain>#{DOMAINS.join('|')})\.com\/(?:questions|q)\/(?<question>\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 000000000..57d5946e4 --- /dev/null +++ b/lib/oneboxer/templates/stack_exchange_onebox.hbrs @@ -0,0 +1,38 @@ +<div class="onebox-result"> + {{#host}} + <div class="source"> + <div class="info"> + <a href="{{link}}" class="track-link" target="_blank"> + {{#favicon}} + <img class="favicon" src="{{favicon}}"> + {{/favicon}} + {{host}} + </a> + </div> + </div> + {{/host}} + + <div class="onebox-result-body"> + {{#owner.profile_image}} + <a href="{{owner.link}}" target="_blank"> + <img alt="{{owner.display_name}}" src="{{owner.profile_image}}"> + </a> + {{/owner.profile_image}} + + <h4> + <a href="{{link}}" target="_blank">{{{title}}}</a> + </h4> + + <div class="date"> + asked by <a href="{{owner.link}}" target="_blank"> + {{owner.display_name}} + </a> + on <a href="{{link}}" target="_blank">{{creation_date}}</a> + </div> + + <div> + <strong>{{tags}}</strong> + </div> + </div> + <div class="clearfix"></div> +</div> 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 000000000..3a4dbd9a7 --- /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