FEATURE: Add support for simplecast oembed. (#403)

FEATURE: Add support for simplecast oembed. (#403)

diff --git a/lib/onebox/engine.rb b/lib/onebox/engine.rb
index 72af7ed..c48077d 100644
--- a/lib/onebox/engine.rb
+++ b/lib/onebox/engine.rb
@@ -182,6 +182,7 @@ require_relative "engine/trello_onebox"
 require_relative "engine/wechat_mp_onebox"
 require_relative "engine/cloudapp_onebox"
 require_relative "engine/wistia_onebox"
+require_relative "engine/simplecast_onebox"
 require_relative "engine/instagram_onebox"
 require_relative "engine/gitlab_blob_onebox"
 require_relative "engine/google_photos_onebox"
diff --git a/lib/onebox/engine/simplecast_onebox.rb b/lib/onebox/engine/simplecast_onebox.rb
new file mode 100644
index 0000000..dae7150
--- /dev/null
+++ b/lib/onebox/engine/simplecast_onebox.rb
@@ -0,0 +1,33 @@
+module Onebox
+  module Engine
+    class SimplecastOnebox
+      include Engine
+      include StandardEmbed
+
+      matches_regexp(/https?:\/\/(.+)?simplecast.com\/(episodes|s)\/.*/)
+      always_https
+
+      def to_html
+        get_oembed.html
+      end
+
+      def placeholder_html
+        oembed = get_oembed
+        return if Onebox::Helpers.blank?(oembed.thumbnail_url)
+        "<img src='#{oembed.thumbnail_url}' #{oembed.title_attr}>"
+      end
+
+      private
+
+      def get_oembed_url
+        if id = url.scan(/\A.*?-([a-zA-Z0-9]*)\Z/).flatten.first
+          oembed_url = "https://simplecast.com/s/#{id}"
+        else
+          oembed_url = url
+        end
+
+        "https://simplecast.com/oembed?url=#{oembed_url}"
+      end
+    end
+  end
+end
diff --git a/lib/onebox/engine/whitelisted_generic_onebox.rb b/lib/onebox/engine/whitelisted_generic_onebox.rb
index 7a9a38e..df4efb8 100644
--- a/lib/onebox/engine/whitelisted_generic_onebox.rb
+++ b/lib/onebox/engine/whitelisted_generic_onebox.rb
@@ -95,7 +95,6 @@ module Onebox
           samsung.com
           screenr.com
           scribd.com
-          simplecast.com
           slideshare.net
           sourceforge.net
           speakerdeck.com
diff --git a/spec/fixtures/simplecast.response b/spec/fixtures/simplecast.response
deleted file mode 100644
index a314b2e..0000000
--- a/spec/fixtures/simplecast.response
+++ /dev/null
@@ -1,125 +0,0 @@
-
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset='utf-8'>
-<script type="text/javascript">window.NREUM||(NREUM={});NREUM.info={"beacon":"bam.nr-data.net","errorBeacon":"bam.nr-data.net","licenseKey":"2a7fc3e9c0","applicationID":"101284474","transactionName":"IAsNRRNXDV5USx9bBwcNAh4SUA5F","queueTime":0,"applicationTime":21,"agent":""}</script>
-<script type="text/javascript">window.NREUM||(NREUM={}),__nr_require=function(e,n,t){function r(t){if(!n[t]){var o=n[t]={exports:{}};e[t][0].call(o.exports,function(n){var o=e[t][1][n];return r(o||n)},o,o.exports)}return n[t].exports}if("function"==typeof __nr_require)return __nr_require;for(var o=0;o<t.length;o++)r(t[o]);return r}({1:[function(e,n,t){function r(){}function o(e,n,t){return function(){return i(e,[c.now()].concat(u(arguments)),n?null:this,t),n?void 0:this}}var i=e("handle"),a=e(3),u=e(4),f=e("ee").get("tracer"),c=e("loader"),s=NREUM;"undefined"==typeof window.newrelic&&(newrelic=s);var p=["setPageViewName","setCustomAttribute","setErrorHandler","finished","addToTrace","inlineHit","addRelease"],d="api-",l=d+"ixn-";a(p,function(e,n){s[n]=o(d+n,!0,"api")}),s.addPageAction=o(d+"addPageAction",!0),s.setCurrentRouteName=o(d+"routeName",!0),n.exports=newrelic,s.interaction=function(){return(new r).get()};var m=r.prototype={createTracer:function(e,n){var t={},r=this,o="function"==typeof n;return i(l+"tracer",[c.now(),e,t],r),function(){if(f.emit((o?"":"no-")+"fn-start",[c.now(),r,o],t),o)try{return n.apply(this,arguments)}catch(e){throw f.emit("fn-err",[arguments,this,e],t),e}finally{f.emit("fn-end",[c.now()],t)}}}};a("actionText,setName,setAttribute,save,ignore,onEnd,getContext,end,get".split(","),function(e,n){m[n]=o(l+n)}),newrelic.noticeError=function(e){"string"==typeof e&&(e=new Error(e)),i("err",[e,c.now()])}},{}],2:[function(e,n,t){function r(e,n){if(!o)return!1;if(e!==o)return!1;if(!n)return!0;if(!i)return!1;for(var t=i.split("."),r=n.split("."),a=0;a<r.length;a++)if(r[a]!==t[a])return!1;return!0}var o=null,i=null,a=/Version\/(\S+)\s+Safari/;if(navigator.userAgent){var u=navigator.userAgent,f=u.match(a);f&&u.indexOf("Chrome")===-1&&u.indexOf("Chromium")===-1&&(o="Safari",i=f[1])}n.exports={agent:o,version:i,match:r}},{}],3:[function(e,n,t){function r(e,n){var t=[],r="",i=0;for(r in e)o.call(e,r)&&(t[i]=n(r,e[r]),i+=1);return t}var o=Object.prototype.hasOwnProperty;n.exports=r},{}],4:[function(e,n,t){function r(e,n,t){n||(n=0),"undefined"==typeof t&&(t=e?e.length:0);for(var r=-1,o=t-n||0,i=Array(o<0?0:o);++r<o;)i[r]=e[n+r];return i}n.exports=r},{}],5:[function(e,n,t){n.exports={exists:"undefined"!=typeof window.performance&&window.performance.timing&&"undefined"!=typeof window.performance.timing.navigationStart}},{}],ee:[function(e,n,t){function r(){}function o(e){function n(e){return e&&e instanceof r?e:e?f(e,u,i):i()}function t(t,r,o,i){if(!d.aborted||i){e&&e(t,r,o);for(var a=n(o),u=v(t),f=u.length,c=0;c<f;c++)u[c].apply(a,r);var p=s[y[t]];return p&&p.push([b,t,r,a]),a}}function l(e,n){h[e]=v(e).concat(n)}function m(e,n){var t=h[e];if(t)for(var r=0;r<t.length;r++)t[r]===n&&t.splice(r,1)}function v(e){return h[e]||[]}function g(e){return p[e]=p[e]||o(t)}function w(e,n){c(e,function(e,t){n=n||"feature",y[t]=n,n in s||(s[n]=[])})}var h={},y={},b={on:l,addEventListener:l,removeEventListener:m,emit:t,get:g,listeners:v,context:n,buffer:w,abort:a,aborted:!1};return b}function i(){return new r}function a(){(s.api||s.feature)&&(d.aborted=!0,s=d.backlog={})}var u="nr@context",f=e("gos"),c=e(3),s={},p={},d=n.exports=o();d.backlog=s},{}],gos:[function(e,n,t){function r(e,n,t){if(o.call(e,n))return e[n];var r=t();if(Object.defineProperty&&Object.keys)try{return Object.defineProperty(e,n,{value:r,writable:!0,enumerable:!1}),r}catch(i){}return e[n]=r,r}var o=Object.prototype.hasOwnProperty;n.exports=r},{}],handle:[function(e,n,t){function r(e,n,t,r){o.buffer([e],r),o.emit(e,n,t)}var o=e("ee").get("handle");n.exports=r,r.ee=o},{}],id:[function(e,n,t){function r(e){var n=typeof e;return!e||"object"!==n&&"function"!==n?-1:e===window?0:a(e,i,function(){return o++})}var o=1,i="nr@id",a=e("gos");n.exports=r},{}],loader:[function(e,n,t){function r(){if(!E++){var e=x.info=NREUM.info,n=l.getElementsByTagName("script")[0];if(setTimeout(s.abort,3e4),!(e&&e.licenseKey&&e.applicationID&&n))return s.abort();c(y,function(n,t){e[n]||(e[n]=t)}),f("mark",["onload",a()+x.offset],null,"api");var t=l.createElement("script");t.src="https://"+e.agent,n.parentNode.insertBefore(t,n)}}function o(){"complete"===l.readyState&&i()}function i(){f("mark",["domContent",a()+x.offset],null,"api")}function a(){return O.exists&&performance.now?Math.round(performance.now()):(u=Math.max((new Date).getTime(),u))-x.offset}var u=(new Date).getTime(),f=e("handle"),c=e(3),s=e("ee"),p=e(2),d=window,l=d.document,m="addEventListener",v="attachEvent",g=d.XMLHttpRequest,w=g&&g.prototype;NREUM.o={ST:setTimeout,SI:d.setImmediate,CT:clearTimeout,XHR:g,REQ:d.Request,EV:d.Event,PR:d.Promise,MO:d.MutationObserver};var h=""+location,y={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",agent:"js-agent.newrelic.com/nr-1099.min.js"},b=g&&w&&w[m]&&!/CriOS/.test(navigator.userAgent),x=n.exports={offset:u,now:a,origin:h,features:{},xhrWrappable:b,userAgent:p};e(1),l[m]?(l[m]("DOMContentLoaded",i,!1),d[m]("load",r,!1)):(l[v]("onreadystatechange",o),d[v]("onload",r)),f("mark",["firstbyte",u],null,"api");var E=0,O=e(5)},{}]},{},["loader"]);</script>
-    <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0' name='viewport'>
-    <title>The Great Discontent | Dan Blackman &amp; Robyn Kanner - The power of vulnerability, self-initiated projects, and how our priorities shape our work |  Episode 6</title>
-    <meta content='interview, interviews, creative, art, artists, creativity, photography, design, ' name='keywords'>

[... diff too long, it was truncated ...]

GitHub sha: a9426270