link_thumbnail 0.1.0

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .*.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in link_thumbnail.gemspec
4
+ gemspec
data/README ADDED
@@ -0,0 +1,56 @@
1
+ link_thumbnail
2
+ ==============
3
+
4
+ Helps you find thumbnail images for a given link, useful for adding context to
5
+ a shared URL. Lets you easily implement the "pick a thumbnail" functionality
6
+ from sharing a link on Facebook or Digg.
7
+
8
+ The approach to discovering an image is multi-tiered, in this order:
9
+ * OpenGraph
10
+ * oEmbed
11
+ - thumbnail_url
12
+ - "photo" type url
13
+ * microformats:
14
+ - basically <img> with "photo" class
15
+ * semantic
16
+ - leverages Readability
17
+
18
+
19
+ Usage / Quickstart
20
+ ==================
21
+ In console:
22
+
23
+ gem install link_thumbnail
24
+
25
+ In irb:
26
+
27
+ require 'link_thumbnail'
28
+ LinkThumbnail.thumbnail_url("http://example.com/a-post/") # => "http://example.com/images/relevant-image.jpg"
29
+
30
+
31
+ License (BSD)
32
+ =============
33
+ Copyright (c) 2011 Toby Matejovsky. All Rights Reserved.
34
+
35
+ Redistribution and use in source and binary forms, with or without modification,
36
+ are permitted provided that the following conditions are met:
37
+
38
+ 1. Redistributions of source code must retain the above copyright notice, this
39
+ list of conditions and the following disclaimer.
40
+
41
+ 2. Redistributions in binary form must reproduce the above copyright notice, this
42
+ list of conditions and the following disclaimer in the documentation and/or other
43
+ materials provided with the distribution.
44
+
45
+ 3. The name of the author may not be used to endorse or promote products derived
46
+ from this software without specific prior written permission.
47
+
48
+ THIS SOFTWARE IS PROVIDED BY [LICENSOR] "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
49
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
50
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
51
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
53
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
55
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
56
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ desc "Run tests"
5
+ task :test do
6
+ $: << "test" << "lib"
7
+ Dir.glob("test/*_test.rb").each{|file| load file}
8
+ end
@@ -0,0 +1,58 @@
1
+ require 'json'
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+ require 'readability'
5
+ require 'readability/document/get_best_candidate'
6
+
7
+ module LinkThumbnail
8
+ class << self
9
+ def thumbnail_url(url)
10
+ source = open(url).read
11
+ doc = Nokogiri.parse(source)
12
+
13
+ if element = doc.xpath('//meta[@property="og:image" and @content]').first
14
+ # OpenGraph
15
+ return element.attributes['content'].value
16
+
17
+ elsif element = doc.xpath('//link[@type="application/json+oembed" and @href]').first
18
+ # oEmbed (JSON)
19
+ oembed_json_response = fetch(element.attributes['href'].value)
20
+ json = JSON.parse(oembed_json_response)
21
+ if src = json['thumbnail_url']
22
+ # Thumbnail (generic)
23
+ return src
24
+ elsif json['type'] == 'photo'
25
+ # Photo type
26
+ return json['url']
27
+ end
28
+
29
+ elsif element = doc.xpath('//link[@type="text/xml+oembed" and @href]').first
30
+ # oEmbed (JSON)
31
+ oembed_xml_response = fetch(element.attributes['href'].value)
32
+ response = Nokogiri.parse(oembed_xml_response)
33
+ if thumbnail = response.xpath('/oembed/thumbnail_url').first
34
+ # Thumbnail (generic)
35
+ return thumbnail.content
36
+ elsif response.xpath('/oembed[type="photo" and url]').first
37
+ # Photo type
38
+ return response.xpath('/oembed/url').first.content
39
+ end
40
+ elsif element = doc.xpath('//img[@class="photo" and @src]').first
41
+ # Microformat
42
+ return element.attributes['src'].value
43
+
44
+ elsif readability_doc = Readability::Document.new(source)
45
+ # Semantic
46
+ if element = readability_doc.get_best_candidate
47
+ if img = element.xpath('//img[@src]').first
48
+ return img.attributes['src'].value
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def fetch(url)
55
+ open(url).read
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module LinkThumbnail
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,18 @@
1
+ module Readability
2
+ class Document
3
+ # This is basically the "content" method, shortened to just pull the top candidate element.
4
+ def get_best_candidate(remove_unlikely_candidates = :default)
5
+ @remove_unlikely_candidates = false if remove_unlikely_candidates == false
6
+
7
+ @html.css("script, style").each { |i| i.remove }
8
+
9
+ remove_unlikely_candidates! if @remove_unlikely_candidates
10
+ transform_misused_divs_into_paragraphs!
11
+ candidates = score_paragraphs(options[:min_text_length])
12
+ best_candidate = select_best_candidate(candidates)
13
+ best_candidate[:elem]
14
+ rescue NoMethodError
15
+ nil
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "link_thumbnail/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "link_thumbnail"
7
+ s.version = LinkThumbnail::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Toby Matejovsky"]
10
+ s.email = ["toby.matejovsky@gmail.com"]
11
+ s.homepage = "https://github.com/tobym/link_thumbnail"
12
+ s.summary = %q{Retrieve thumbnail images for a given URL.}
13
+ s.description = %q{Given a URL, retrieves thumbnail images (similar to when you share a link on Facebook or Digg).}
14
+
15
+ s.rubyforge_project = "link_thumbnail"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency(%q<json>, ["~> 1.4.0"])
23
+ s.add_dependency(%q<nokogiri>, ["~> 1.4.0"])
24
+ s.add_dependency(%q<ruby-readability>, ["~> 0.2.3"])
25
+ s.add_development_dependency(%q<mocha>, [">= 0"])
26
+
27
+ end
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <head>
3
+ <title>Example</title>
4
+ </head>
5
+ <body>
6
+ <div class="hmedia">
7
+ <img class="photo" src="http://example.com/thumb.jpg" />
8
+ </div>
9
+ </body>
10
+ </html>
@@ -0,0 +1,7 @@
1
+ <!-- Based on example from http://www.oembed.com/#section4 -->
2
+ <html>
3
+ <head>
4
+ <link rel="alternate" type="application/json+oembed" href="http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json" title="Bacon Lollys oEmbed Profile" />
5
+ <link rel="alternate" type="text/xml+oembed" href="http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=xml" title="Bacon Lollys oEmbed Profile" />
6
+ </head>
7
+ </html>
@@ -0,0 +1,6 @@
1
+ <!-- Based on example from http://www.oembed.com/#section4 -->
2
+ <html>
3
+ <head>
4
+ <link rel="alternate" type="application/json+oembed" href="http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json" title="Bacon Lollys oEmbed Profile" />
5
+ </head>
6
+ </html>
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": "1.0",
3
+ "type": "photo",
4
+ "width": 240,
5
+ "height": 160,
6
+ "title": "ZB8T0193",
7
+ "url": "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg",
8
+ "author_name": "Bees",
9
+ "author_url": "http://www.flickr.com/photos/bees/",
10
+ "provider_name": "Flickr",
11
+ "provider_url": "http://www.flickr.com/"
12
+ }
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+ <oembed>
3
+ <version>1.0</version>
4
+ <type>photo</type>
5
+ <width>240</width>
6
+ <height>160</height>
7
+ <url>http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg</url>
8
+ </oembed>
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": "1.0",
3
+ "type": "photo",
4
+ "width": 240,
5
+ "height": 160,
6
+ "title": "ZB8T0193",
7
+ "url": "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg",
8
+ "author_name": "Bees",
9
+ "author_url": "http://www.flickr.com/photos/bees/",
10
+ "provider_name": "Flickr",
11
+ "provider_url": "http://www.flickr.com/",
12
+ "thumbnail_url": "http://example.com/thumbnail.jpg",
13
+ "thumbnail_width": 150,
14
+ "thumbnail_height": 150
15
+ }
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
+ <oembed>
3
+ <version>1.0</version>
4
+ <type>link</type>
5
+ <thumbnail_url>http://example.com/thumbnail.jpg</thumbnail_url>
6
+ <thumbnail_width>150</thumbnail_width>
7
+ <thumbnail_height>150</thumbnail_height>
8
+ </oembed>
@@ -0,0 +1,6 @@
1
+ <!-- Based on example from http://www.oembed.com/#section4 -->
2
+ <html>
3
+ <head>
4
+ <link rel="alternate" type="text/xml+oembed" href="http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=xml" title="Bacon Lollys oEmbed Profile" />
5
+ </head>
6
+ </html>
@@ -0,0 +1,10 @@
1
+ <!-- Based on example from http://ogp.me/ -->
2
+ <html xmlns:og="http://ogp.me/ns#">
3
+ <head>
4
+ <title>The Rock (1996)</title>
5
+ <meta property="og:title" content="The Rock" />
6
+ <meta property="og:type" content="movie" />
7
+ <meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />
8
+ <meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg" />
9
+ </head>
10
+ </html>
@@ -0,0 +1,10 @@
1
+ <!-- Based on example from http://ogp.me/ -->
2
+ <html xmlns:og="http://ogp.me/ns#">
3
+ <head>
4
+ <title>The Rock (1996)</title>
5
+ <meta property="og:title" content="The Rock" />
6
+ <meta property="og:type" content="movie" />
7
+ <meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />
8
+ <meta property="og:image" />
9
+ </head>
10
+ </html>
@@ -0,0 +1,9 @@
1
+ <!-- Based on example from http://ogp.me/ -->
2
+ <html xmlns:og="http://ogp.me/ns#">
3
+ <head>
4
+ <title>The Rock (1996)</title>
5
+ <meta property="og:title" content="The Rock" />
6
+ <meta property="og:type" content="movie" />
7
+ <meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />
8
+ </head>
9
+ </html>
@@ -0,0 +1,409 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+
4
+ <head profile="http://gmpg.org/xfn/11">
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+
7
+ <!-- nivi title> Launch: The AngelList Blog</title -->
8
+ <title>
9
+ Launch: The AngelList Blog &#045; Venture Hacks </title>
10
+
11
+ <meta name="generator" content="WordPress 3.1.1-alpha-17490" /> <!-- leave this for stats -->
12
+
13
+ <link rel="stylesheet" href="http://venturehacks.com/wordpress/wp-content/themes/Cutline 1.1/style.css" type="text/css" media="screen" />
14
+ <link rel="stylesheet" href="http://venturehacks.com/wordpress/wp-content/themes/Cutline 1.1/custom.css" type="text/css" media="screen" />
15
+ <!--[if lte IE 7]>
16
+ <link rel="stylesheet" type="text/css" href="http://venturehacks.com/wordpress/wp-content/themes/Cutline 1.1/ie7.css" media="screen" />
17
+ <![endif]-->
18
+ <!--[if lte IE 6]>
19
+ <link rel="stylesheet" type="text/css" href="http://venturehacks.com/wordpress/wp-content/themes/Cutline 1.1/ie6.css" media="screen" />
20
+ <![endif]-->
21
+ <link rel="alternate" type="application/rss+xml" title="Venture Hacks RSS Feed" href="http://feeds.venturehacks.com/venturehacks" />
22
+ <link rel="pingback" href="http://venturehacks.com/wordpress/xmlrpc.php" />
23
+
24
+ <link rel="alternate" type="application/rss+xml" title="Venture Hacks &raquo; Launch: The AngelList Blog Comments Feed" href="http://venturehacks.com/articles/angellist-blog/feed" />
25
+ <link rel='stylesheet' id='btc-css-css' href='http://venturehacks.com/wordpress/?btc_action=btc_css&#038;ver=1.0' type='text/css' media='screen' />
26
+ <script type='text/javascript' src='http://venturehacks.com/wordpress/wp-includes/js/l10n.js?ver=20101110'></script>
27
+ <script type='text/javascript' src='http://venturehacks.com/wordpress/wp-includes/js/jquery/jquery.js?ver=1.4.4'></script>
28
+ <script type='text/javascript' src='http://venturehacks.com/wordpress/wp-content/plugins/google-analyticator/external-tracking.min.js?ver=6.1.2'></script>
29
+ <link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://venturehacks.com/wordpress/xmlrpc.php?rsd" />
30
+ <link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://venturehacks.com/wordpress/wp-includes/wlwmanifest.xml" />
31
+ <link rel='index' title='Venture Hacks' href='http://venturehacks.com' />
32
+ <link rel='start' title='Term Sheet Hacks: Get a Great Deal' href='http://venturehacks.com/articles/term-sheet-hacks' />
33
+ <link rel='prev' title='The first 1000x in valuation is the easiest' href='http://venturehacks.com/articles/first-1000x' />
34
+ <meta name="generator" content="WordPress 3.1.1-alpha-17490" />
35
+ <link rel='canonical' href='http://venturehacks.com/articles/angellist-blog' />
36
+ <link rel='shortlink' href='http://wp.me/pGzf1-2eG' />
37
+ <!-- Google Analytics Tracking by Google Analyticator 6.1.2: http://ronaldheft.com/code/analyticator/ -->
38
+ <script type="text/javascript">
39
+ var analyticsFileTypes = [''];
40
+ var analyticsEventTracking = 'enabled';
41
+ </script>
42
+ <script type="text/javascript">
43
+ var _gaq = _gaq || [];
44
+ _gaq.push(['_setAccount', 'UA-1602828-1']);
45
+ _gaq.push(['_trackPageview']);
46
+
47
+ (function() {
48
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
49
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
50
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
51
+ })();
52
+ </script>
53
+
54
+ <!-- nivi for google webmaster tools -->
55
+ <meta name="verify-v1" content="pl+LkCgPh5ZLx4TN3hPQ3lfD2PMSU5tiQ8uVwAtmL5o=" />
56
+
57
+ <!-- link rel="shortcut icon" href="http://venturehacks.com/wordpress/wp-content/themes/Cutline 1.1/favicon.ico" / -->
58
+
59
+ <link rel="shortcut icon" href="http://venturehacks.com/wordpress/wp-content/uploads/2009/10/Peace-Logo.jpg" />
60
+
61
+ </head>
62
+ <body class="custom">
63
+
64
+ <script type='text/javascript' src='http://track3.mybloglog.com/js/jsserv.php?mblID=2007040315581297'></script>
65
+
66
+ <div id="container">
67
+
68
+ <div id="masthead" style="background-color:white;">
69
+ <!-- p id="login_register"><a href="/wordpress/wp-login.php">Login</a></p -->
70
+ <!-- div style="float:left;padding:5px 0 5px 10px;"><img src="/wordpress/wp-content/uploads/2007/04/vh-100.png"></div -->
71
+
72
+ <h1><img align="absbottom" width=45 src="http://venturehacks.com/wordpress/wp-content/uploads/2009/10/Peace-Logo.jpg"><a href="http://venturehacks.com">Venture Hacks</a></h1>
73
+ <h3>Good advice for startups.</h3>
74
+ <!-- div id="disclaimer"><em><a href="/disclaimer" style="color:red;text-align:left;">Disclaimer: This is not legal advice.</a></em></div -->
75
+ <div class="caption" style="font-size: 9px; font-family: helvetica, arial, sans-serif; position: absolute; top: 10px; right: 63px;">
76
+ SUPPORTED BY<br>
77
+ <a href="http://www.kauffman.org/" title="The Kauffman Foundation" target="_blank"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2011/02/kauffman.png" alt="The Kauffman Foundation" style="width: 180px;"></a>
78
+ </div>
79
+ </div>
80
+
81
+ <ul id="nav">
82
+ <!-- li><a href="http://venturehacks.com">Home</a></li -->
83
+
84
+ <li><a href="/products">Products</a></li>
85
+
86
+ <li><a href="http://venturehacks.com/archives">Archives</a></li>
87
+ <!-- nivi <li><a href="http://venturehacks.com/term-sheet-hacks">Hacks</a></li>-->
88
+ <!-- li><a href="http://venturehacks.com/recommended">Recommended</a></li -->
89
+ <li><a href="http://twitter.com/venturehacks" target="window">@venturehacks</a></li>
90
+ <li><a href="/bookstore">Books</a></li>
91
+ <li><a href="http://angel.co" >AngelList</a></li>
92
+ <!-- li><a href="/supporters">Supporters</a></li -->
93
+ <li><a href="/about">About</a></li>
94
+ <li class="rss"><a href="http://feeds.venturehacks.com/venturehacks">RSS</a></li>
95
+ </ul>
96
+
97
+ <div id="header_img">
98
+ <img src="http://venturehacks.com/wordpress/wp-content/themes/Cutline 1.1/images/header_2.jpg" width="770" height="0" alt="Venture Hacks header image 2" title="Venture Hacks header image 2" />
99
+ </div>
100
+ <div id="content_box">
101
+
102
+ <div id="content" class="posts">
103
+
104
+ <!-- div style='border-bottom: 3px double #888; border-top: 3px double #888; padding-top: 1em'>
105
+ <center><iframe src="/highlights" style='border:0; height:24em; width: 40em' scrolling="no" width="450px"></iframe>
106
+ </center>
107
+ </div>
108
+ <p style='height: 2em'/ -->
109
+
110
+
111
+ <!-- nivi ?php include (TEMPLATEPATH . '/navigation.php'); ? -->
112
+
113
+ <h2><a href="http://venturehacks.com/articles/angellist-blog" rel="bookmark" title="Permanent Link to Launch: The AngelList Blog">Launch: The AngelList Blog</a></h2>
114
+ <!-- nivi h2>Launch: The AngelList Blog</h2 -->
115
+
116
+ <h4><p style="color:black;padding-bottom:2px;font-family:helvetica;font-style:normal;">by Nivi on March 23rd, 2011<br /><!-- nivi &middot; --> <!-- nivi a href="http://venturehacks.com/articles/angellist-blog#comments">No Comments</a --></h4>
117
+ <div class="entry">
118
+ <p>AngelList now has a sweet new <a href="http://blog.angel.co">blog</a>. Therein, the AngelList <a href="http://twitter.com/#!/angellist/team/members">team</a> expounds upon the latest features, including screenshots that are sure to bring you great joy.</p>
119
+ <p><img class="aligncenter" src="http://venturehacks.com/wordpress/wp-content/uploads/2011/03/Page_3.png" alt="" width="450" /></p>
120
+ <p><img class="aligncenter" src="http://venturehacks.com/wordpress/wp-content/uploads/2011/03/step2.png" alt="" width="450" /></p>
121
+ <p><img class="aligncenter" src="http://venturehacks.com/wordpress/wp-content/uploads/2011/03/step3.png" alt="" width="450" /></p>
122
+ <p>Our team is using the AngelList blog to post our weekly progress. We used to put it on Yammer, but now we&#8217;re posting it publicly on the blog. So don&#8217;t expect polished posts with the &#8220;final&#8221; version of each feature. We&#8217;ll be sharing works in progress (that we&#8217;ve shipped).</p>
123
+ <p>So check out the <a href="http://blog.angel.co">AngelList blog</a> and stay up to date on our endless product developments. We promise a steady stream of pretty pictures.</p>
124
+ </div>
125
+
126
+ <!-- nivi --><script src="http://feeds.feedburner.com/~s/venturehacks?i=http://venturehacks.com/articles/angellist-blog" type="text/javascript" charset="utf-8"></script>
127
+
128
+ <p class="tagged"><strong>Learn more about:</strong> <a href="http://venturehacks.com/topics/angellist" title="View all posts in AngelList" rel="category tag">AngelList</a></p>
129
+ <div class="clear"></div>
130
+
131
+
132
+ <!-- You can start editing here. -->
133
+
134
+ <!--<p><a href='http://venturehacks.com/articles/angellist-blog/feed'><abbr title="Really Simple Syndication">RSS</abbr> feed</a>
135
+ </p>-->
136
+
137
+ <div id="comments">
138
+ <h3 class="comments_headers">0 responses so far &middot; <a href='http://venturehacks.com/articles/angellist-blog/feed'>Comments RSS</a></h3>
139
+ <div class="#commentlist">
140
+ </div>
141
+
142
+ <div class="comment" style="padding-left:15px;">
143
+ <h3 id="respond" class="comments_headers">Trackback responses to this post</h3>
144
+ <ul class="comment_nivi_login" style="margin-top:5px;">
145
+ </ul>
146
+ </div>
147
+
148
+ <div id="addcomment" class="comment">
149
+ <a id="addcommentanchor" name="addcommentanchor"></a>
150
+ <form action="http://venturehacks.com/wordpress/wp-comments-post.php" method="post" id="commentform">
151
+ <div class="add">
152
+ <h3 id="respond" class="comments_headers">
153
+ Leave a Comment or <!-- nivi --><a href="http://venturehacks.com/articles/angellist-blog/trackback">Trackback</a></h3>
154
+ <p id="reroot" style="display: none;">
155
+ <small><a href="#" onclick="reRoot(); return false;" class="reply_button">Cancel Reply</a></small>
156
+ </p>
157
+ <!-- <p class="comment_nivi_login"><a href="/wordpress/wp-login.php">Login</a> / <a href="/wordpress/wp-login.php?action=register">Register</a> / <a href="/wordpress/wp-login.php?action=register">Register Anonymously</a> first to use a Venture Hacks account.</p>
158
+ <p class="comment_nivi_login">- or -</p>
159
+ <p class="comment_nivi_login">Leave a comment as an unregistered user:</p> -->
160
+ <p><input class="text_input" type="text" name="author" id="author" value="" tabindex="1" /><label for="author"><!-- nivi --><span class="comment_nivi_label">name (optional)</span></label></p>
161
+ <p><input class="text_input" type="text" name="email" id="email" value="" tabindex="2" /><label for="email"><span class="comment_nivi_label">email (optional &amp; unpublished)</span></label></p>
162
+ <p><input class="text_input" type="text" name="url" id="url" value="" tabindex="3" /><label for="url"><span class="comment_nivi_label">site (optional)</span></label></p>
163
+
164
+ <!-- nivi --><p id="comment_textarea_container"><textarea class="text_input text_area" name="comment" id="comment" rows="15" cols="50" tabindex="4"></textarea><label for="comment"><span class="comment_nivi_label" ><strong style="vertical-align:top;">comment</strong></span></label></p>
165
+ <p class="comment_nivi_label">Basic HTML is allowed (a href, strong, em, blockquote, strike).</p>
166
+ <div>
167
+ <input type="hidden" name="comment_post_ID" value="8598" />
168
+ <input type="hidden" name="redirect_to" value="/articles/angellist-blog" />
169
+ <input onclick="if(typeof(onAddComment) == 'function') { onAddComment(); } else { alert('ERROR:\nIt looks like the website administrator hasn\'t activated the Brians Threaded Comments plugin from the plugin page'); };" name="addcommentbutton" class="form_submit" type="button" id="addcommentbutton" value="Submit" tabindex="5" />
170
+ </div>
171
+ </div>
172
+ <p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="22e23243ba" /></p><input type="hidden" id="comment_reply_ID" name="comment_reply_ID" value="0" /></form>
173
+ </div>
174
+ </div>
175
+
176
+ </div>
177
+
178
+ <div id="sidebar">
179
+ <ul class="sidebar_list">
180
+ <li class="widget">
181
+ <div id="advertisement">
182
+ <div class="caption">Our Ad</div>
183
+ <center><script type="text/javascript" src="http://engine.influads.com/publisher/v/Css"></script></center>
184
+ </div>
185
+
186
+
187
+
188
+
189
+ <br />
190
+ <div id="advertisement">
191
+ <div class="caption">Our Books</div>
192
+
193
+ <!-- a href="http://venturehacks.com/pitching"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2009/02/pitching-hacks.png" /></a -->
194
+
195
+ <a href="http://leanpub.com/venturehacks/"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2010/04/bible.png" /></a>
196
+ <p>Every post in one book. Constantly updated. Check out the <a href="http://s3.amazonaws.com/samples.leanpub.com/venturehacks-sample.pdf">free sample</a> (pdf)</p>
197
+ <br />
198
+ <a href="http://venturehacks.com/pitching"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2009/10/pitching-hacks.png" /></a>
199
+ <p>Check out the <a href="http://venturehacks.com/pitching">free samples</a></p>
200
+ </div>
201
+ <!-- div id="advertisement">
202
+ <div class="caption">Our Spreadsheet</div>
203
+
204
+ <a href="http://venturehacks.com/articles/cap-table"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2009/10/cap-table.png" /></a>
205
+ <p>Check out the <a href="http://venturehacks.com/articles/cap-table">video tour</a>.</p>
206
+ </div -->
207
+ <!-- a href="http://crv.com" onClick="javascript: pageTracker._trackPageview('/outgoing/crv.com');"><img src="http://venturehacks.com/wordpress/wp-content/themes/Cutline 1.1/images/advertisements/crv.png" /></a>
208
+ <p><a href="http://crv.com" onClick="javascript: pageTracker._trackPageview('/outgoing/crv.com');">Charles River Ventures</a>: We back people who want to change the world.</p -->
209
+
210
+ <!-- div id="advertisement">
211
+ <div class="caption"><a href="#supporter" name="supporter" style="color:black;text-decoration:none;">Supporter Posts</a></div>
212
+ <br />
213
+ <a href="http://walkercorporatelaw.com/blog" onClick="javascript: pageTracker._trackPageview('/outgoing/walkercorporatelaw.com/blog');"><img align=right width=50 style="padding: 0 0 0 10px" src="http://venturehacks.com/wordpress/wp-content/uploads/2010/01/walker.png" /></a>
214
+ <p align=left text-color="#ffffff"><a text-color="#ffffff" href="http://walkercorporatelaw.com/blog/" onClick="javascript: pageTracker._trackPageview('/outgoing/walkercorporatelaw.com/blog');"><em>Scott Edward Walker</em></a></p>
215
+
216
+ <p align=left ><a style="font-size:12px;font-family:helvetica;font-weight:bold;" href="http://walkercorporatelaw.com/startup-issues/ask-the-attorney-founder-vesting/" onClick="javascript: pageTracker._trackPageview('/outgoing/walkercorporatelaw.com/blog');">“Ask the Attorney” – Founder Vesting</a><br />
217
+
218
+ This post is part of a new series entitled “Ask the Attorney,” which I am writing for VentureBeat (one of my favorite websites for entrepreneurs). As the VentureBeat Editor notes on the site: “Ask the Attorney is a new VentureBeat… <a href="http://walkercorporatelaw.com/startup-issues/ask-the-attorney-founder-vesting/" onClick="javascript: pageTracker._trackPageview('/outgoing/walkercorporatelaw.com/blog');">read more&rarr;</a></p>
219
+ </div -->
220
+
221
+ <!-- a href="http://www.linkedin.com/in/navalr" onClick="javascript: pageTracker._trackPageview('/outgoing/startupboy.com');"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2009/09/naval.jpg" /></a>
222
+ <p><a href="http://www.linkedin.com/in/navalr" onClick="javascript: pageTracker._trackPageview('/outgoing/startupboy.com');">Naval Ravikant</a>: Angel investor, Venture Hacks author.</p -->
223
+
224
+
225
+ </li>
226
+ <li class="widget">
227
+ <h2><a href="/about">About Us</a></h2>
228
+ <center><a href="http://www.nivi.com/"><img width=100 src="http://venturehacks.com/wordpress/wp-content/uploads/2007/04/nivi-portrait.jpg"></a><a href="http://www.startupboy.com/"><img width=100 src="http://venturehacks.com/wordpress/wp-content/uploads/2007/12/naval-portrait.jpg"></a></center><br />
229
+ We're <a href="http://nivi.com">Nivi</a> (<a href="http://www.linkedin.com/in/bnivi">bio</a>) and <a href="http://www.startupboy.com/">Naval</a> (<a href="http://startupboy.com/about/">bio</a>). We’re founders (Epinions), investors (Twitter), students (life), and advisors (billions).<br /><br />
230
+ Read some fun <a href="/about#reviews"> reviews of this site</a>. </li>
231
+ <li class="widget">
232
+ <h2>Subscribe</h2>
233
+ <form action="http://www.feedburner.com/fb/a/emailverify" method="post" target="popupwindow" onsubmit="window.open('http://www.feedburner.com', 'popupwindow', 'scrollbars=yes,width=550,height=520');return true"><a href="http://feeds.venturehacks.com/venturehacks">RSS</a> &nbsp;or &nbsp;<input type="text" style="width:100px" name="email"/><input type="hidden" value="http://feeds.feedburner.com/~e?ffid=805452" name="url"/><input type="hidden" value="Venture Hacks" name="title"/>&nbsp;<input type="submit" value="Email" /></form>
234
+ </li>
235
+
236
+ <li class="widget">
237
+ <h2>Contact</h2>
238
+ A poem: We read every email, but can't respond to most, or we wouldn't have time, to write a post. <a href="mailto:&#x66;&#x6f;&#x75;&#x6e;&#x64;&#x65;&#x72;&#x73;&#x40;&#x76;&#x65;&#x6e;&#x74;&#x75;&#x72;&#x65;&#x68;&#x61;&#x63;&#x6b;&#x73;&#x2e;&#x63;&#x6f;&#x6d;">&#x66;&#x6f;&#x75;&#x6e;&#x64;&#x65;&#x72;&#x73;&#x40;&#x76;&#x65;&#x6e;&#x74;&#x75;&#x72;&#x65;&#x68;&#x61;&#x63;&#x6b;&#x73;&#x2e;&#x63;&#x6f;&#x6d;</a>
239
+ <br />(Help requests from paying customers are answered within 24 hours.)
240
+ </li>
241
+
242
+ <li class="widget">
243
+ <h2><a title="popular" name="popular" href="#popular">Popular Posts</a></h2>
244
+ <ul class='wppp_list'>
245
+ <li><a href='http://venturehacks.com/angellist' title='AngelList'>AngelList</a></li>
246
+ <li><a href='http://venturehacks.com/archives' title='Archives'>Archives</a></li>
247
+ <li><a href='http://venturehacks.com/articles/cap-table' title='How to make a cap table'>How to make a cap table</a></li>
248
+ <li><a href='http://venturehacks.com/articles/option-pool-shuffle' title='The Option Pool Shuffle'>The Option Pool Shuffle</a></li>
249
+ <li><a href='http://venturehacks.com/products' title='Products'>Products</a></li>
250
+ <li><a href='http://venturehacks.com/articles/sean-ellis-interview' title='How to bring a product to market / A very rare interview with Sean Ellis'>How to bring a product to market / A very rare interview with Sean Ellis</a></li>
251
+ <li><a href='http://venturehacks.com/articles/elevator-pitch' title='What should I send investors? Part 1: Elevator Pitch'>What should I send investors? Part 1: Elevator Pitch</a></li>
252
+ </ul>
253
+ </li>
254
+
255
+ <!-- ?php get_links_list('id'); ? -->
256
+ <!-- li class="widget">
257
+ <h2>Our Personal Blogs</h2>
258
+ <ul>
259
+ <li><a href="http://nivi.com/blog">Nivi</a></li>
260
+ <li><a href="http://www.startupboy.com">Naval</a></li>
261
+ </ul>
262
+ </li -->
263
+
264
+
265
+ <li class="widget">
266
+ <h2>Search</h2>
267
+ <form method="get" id="search_form" action="http://venturehacks.com/">
268
+ <input type="text" class="search_input" value="Your search here" name="s" id="s" onfocus="if (this.value == 'Your search here') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Your search here';}" />
269
+ <input type="hidden" id="searchsubmit" value="Search" />
270
+ </form>
271
+ </li>
272
+
273
+
274
+ <li class="widget">
275
+ <h2><a href="http://twitter.com/venturehacks">Twitter</a></h2>
276
+ <script src="http://widgets.twimg.com/j/2/widget.js"></script>
277
+ <script>
278
+ new TWTR.Widget({
279
+ version: 2,
280
+ type: 'profile',
281
+ rpp: 4,
282
+ interval: 6000,
283
+ width: 225,
284
+ height: 300,
285
+ theme: {
286
+ shell: {
287
+ background: '#a6a4a6',
288
+ color: '#ffffff'
289
+ },
290
+ tweets: {
291
+ background: '#ffffff',
292
+ color: '#000000',
293
+ links: '#12a81c'
294
+ }
295
+ },
296
+ features: {
297
+ scrollbar: false,
298
+ loop: false,
299
+ live: false,
300
+ hashtags: true,
301
+ timestamp: true,
302
+ avatars: false,
303
+ behavior: 'all'
304
+ }
305
+ }).render().setUser('venturehacks').start();
306
+ </script></li>
307
+ <li class="widget">
308
+
309
+ <script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US"></script><script type="text/javascript">FB.init("efcf7026d2d04a215631597b77fe9e7e");</script><fb:fan profile_id="70612138702" stream="0" connections="10" width="235"></fb:fan><div style="font-size:8px; padding-left:10px"><a href="http://www.facebook.com/pages/Venture-Hacks/70612138702">Venture Hacks on Facebook</a> </div>
310
+ </li>
311
+
312
+
313
+
314
+ <!-- li class="widget" >
315
+ <h2><a href="http://twitter.com/venturehacks">Twitter</a></h2>
316
+ <script src="http://widgets.twimg.com/j/2/widget.js"></script>
317
+ <script>
318
+ new TWTR.Widget({
319
+ version: 2,
320
+ type: 'search',
321
+ search: 'venturehacks',
322
+ interval: 20000,
323
+ title: 'Venture Hacks on Twitter',
324
+ subject: '',
325
+ width: 225,
326
+ height: 500,
327
+ theme: {
328
+ shell: {
329
+ background: '#a6a4a6',
330
+ color: '#ffffff'
331
+ },
332
+ tweets: {
333
+ background: '#ffffff',
334
+ color: '#000000',
335
+ links: '#12a81c'
336
+ }
337
+ },
338
+ features: {
339
+ scrollbar: true,
340
+ loop: false,
341
+ live: true,
342
+ hashtags: true,
343
+ timestamp: true,
344
+ avatars: true,
345
+ behavior: 'all'
346
+ }
347
+ }).render().start();
348
+ </script>
349
+ </li -->
350
+
351
+
352
+ <div id="advertisement">
353
+ <div class="caption">Our Daily Newsletter</div>
354
+ <a href="http://venturehacks.com/articles/best-advice"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2009/12/startupnews.png" /></a>
355
+ <p>Sign up via <a href="http://eepurl.com/bf28D">email</a> or <a href="http://feeds.venturehacks.com/venturehacks-twitter">RSS</a>. <a href="http://venturehacks.com/articles/best-advice">Learn more</a>.</p>
356
+ </div>
357
+ <br />
358
+
359
+ <div id="advertisement">
360
+ <div class="caption">Our Bookstore</div>
361
+ <a href="http://venturehacks.com/bookstore/"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2009/12/bookstore.png" /></a>
362
+ <p>See our <a href="http://venturehacks.com/bookstore">recommendations</a>.</p>
363
+ </div>
364
+ <br />
365
+
366
+ <div id="advertisement">
367
+ <div class="caption">All our products</div>
368
+
369
+ <a href="http://venturehacks.com/happy-meal"><img src="http://venturehacks.com/wordpress/wp-content/uploads/2009/12/happymeal.png" alt="" width="100" /></a>
370
+
371
+ <p><a href="http://venturehacks.com/pitching">Pitching Hacks</a>, <a href="http://venturehacks.com/articles/cap-table">Cap Table</a>, and <a href="http://venturehacks.com/articles/co-founder-interview">Co-founder Interview</a>. <em>Save 30%</em>. <a href="http://venturehacks.com/happy-meal">Buy it here</a>.</p>
372
+ </div>
373
+ <br />
374
+
375
+ <div id="advertisement"><em><a href="/disclaimer" style="color:red;text-align:left;size:2em;">Disclaimer: This is not legal advice.</a></em></div>
376
+
377
+
378
+ <!-- li class="widget">
379
+ <script type="text/javascript" src="http://pub.mybloglog.com/comm2.php?mblID=2007040315581297&amp;c_width=180&amp;c_sn_opt=y&amp;c_rows=7&amp;c_img_size=f&amp;c_heading_text=Venture+Hacks+Community&amp;c_color_heading_bg=FF66CC&amp;c_color_heading=FFFFFF&amp;c_color_link_bg=FFFFFF&amp;c_color_link=000000&amp;c_color_bottom_bg=FF66CC"></script>
380
+ </li -->
381
+
382
+ </ul>
383
+ </div>
384
+
385
+ </div>
386
+
387
+ <script type="text/javascript" src="http://www.wordvu.com/js/copyvu.js?id=1_ZG1WdWRIVnlaV2hoWTJ0ekxtTnZiUT09"></script>
388
+
389
+ <div id="footer">
390
+ <p>&copy; 2007 Venture Hacks (not including the pictures) &mdash; <!-- nivi a href="http://venturehacks.com/sitemap/">Sitemap</a --> <a href="http://cutline.tubetorial.com/">Cutline</a> Theme by <a href="http://www.tubetorial.com">Chris Pearson</a></p>
391
+ <script type='text/javascript' src='http://venturehacks.com/wordpress/?btc_action=btc_js&#038;ver=1.0'></script>
392
+ <!--stats_footer_test--><script src="http://stats.wordpress.com/e-201112.js" type="text/javascript"></script>
393
+ <script type="text/javascript">
394
+ st_go({blog:'10145247',v:'ext',post:'8598'});
395
+ var load_cmc = function(){linktracker_init(10145247,8598,2);};
396
+ if ( typeof addLoadEvent != 'undefined' ) addLoadEvent(load_cmc);
397
+ else load_cmc();
398
+ </script>
399
+ </div>
400
+ </div>
401
+
402
+ <!-- nivi -->
403
+ <script type="text/javascript" src="http://cetrk.com/pages/scripts/0004/6591.js"> </script>
404
+
405
+ </body>
406
+ </html>
407
+ <!-- Dynamic page generated in 0.396 seconds. -->
408
+ <!-- Cached page generated by WP-Super-Cache on 2011-03-23 21:41:21 -->
409
+ <!-- super cache -->
@@ -0,0 +1,73 @@
1
+ require 'link_thumbnail'
2
+ require 'minitest/autorun'
3
+ require 'mocha'
4
+
5
+ class LinkThumbnailTest < MiniTest::Unit::TestCase
6
+
7
+ FIXTURES = {
8
+ :opengraph => File.join(File.dirname(__FILE__), "fixtures", "open_graph.html"),
9
+ :opengraph_no_tag => File.join(File.dirname(__FILE__), "fixtures", "open_graph_no_tag.html"),
10
+ :opengraph_bad_tag => File.join(File.dirname(__FILE__), "fixtures", "open_graph_bad_tag.html"),
11
+
12
+ :oembed_json => File.join(File.dirname(__FILE__), "fixtures", "oembed_json.html"),
13
+ :oembed_json_photo_response => File.join(File.dirname(__FILE__), "fixtures", "oembed_photo_response.json"),
14
+ :oembed_json_thumbnail_response => File.join(File.dirname(__FILE__), "fixtures", "oembed_thumbnail_response.json"),
15
+
16
+ :oembed_xml => File.join(File.dirname(__FILE__), "fixtures", "oembed_xml.html"),
17
+ :oembed_xml_thumbnail_response => File.join(File.dirname(__FILE__), "fixtures", "oembed_thumbnail_response.xml"),
18
+ :oembed_xml_photo_response => File.join(File.dirname(__FILE__), "fixtures", "oembed_photo_response.xml"),
19
+
20
+ :microformat => File.join(File.dirname(__FILE__), "fixtures", "microformat.html"),
21
+
22
+ :semantic => File.join(File.dirname(__FILE__), "fixtures", "semantic.html"),
23
+ }
24
+
25
+ def test_opengraph
26
+ assert_equal "http://ia.media-imdb.com/images/rock.jpg", LinkThumbnail.thumbnail_url(FIXTURES[:opengraph])
27
+ end
28
+
29
+ def test_opengraph_no_tag
30
+ assert_nil LinkThumbnail.thumbnail_url(FIXTURES[:opengraph_no_tag])
31
+ end
32
+
33
+ def test_opengraph_bad_tag
34
+ assert_nil LinkThumbnail.thumbnail_url(FIXTURES[:opengraph_bad_tag])
35
+ end
36
+
37
+ def test_oembed_thumbnail_json
38
+ LinkThumbnail.expects('fetch').with("http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json").returns(open(FIXTURES[:oembed_json_thumbnail_response]).read)
39
+
40
+ assert_equal "http://example.com/thumbnail.jpg",
41
+ LinkThumbnail.thumbnail_url(FIXTURES[:oembed_json])
42
+ end
43
+
44
+ def test_oembed_photo_json
45
+ LinkThumbnail.expects('fetch').with("http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=json").returns(open(FIXTURES[:oembed_json_photo_response]).read)
46
+
47
+ assert_equal "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg",
48
+ LinkThumbnail.thumbnail_url(FIXTURES[:oembed_json])
49
+ end
50
+
51
+ def test_oembed_thumbnail_xml
52
+ LinkThumbnail.expects('fetch').with("http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=xml").returns(open(FIXTURES[:oembed_xml_thumbnail_response]).read)
53
+
54
+ assert_equal "http://example.com/thumbnail.jpg", LinkThumbnail.thumbnail_url(FIXTURES[:oembed_xml])
55
+ end
56
+
57
+ def test_oembed_photo_xml
58
+ LinkThumbnail.expects('fetch').with("http://flickr.com/services/oembed?url=http%3A//flickr.com/photos/bees/2362225867/&format=xml").returns(open(FIXTURES[:oembed_xml_photo_response]).read)
59
+
60
+ assert_equal "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg",
61
+ LinkThumbnail.thumbnail_url(FIXTURES[:oembed_xml])
62
+ end
63
+
64
+ def test_microformat
65
+ assert_equal "http://example.com/thumb.jpg", LinkThumbnail.thumbnail_url(FIXTURES[:microformat])
66
+ end
67
+
68
+ def test_semantic
69
+ assert_equal "http://venturehacks.com/wordpress/wp-content/uploads/2009/10/Peace-Logo.jpg",
70
+ LinkThumbnail.thumbnail_url(FIXTURES[:semantic])
71
+ end
72
+
73
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: link_thumbnail
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Toby Matejovsky
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-03-24 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 4
31
+ - 0
32
+ version: 1.4.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: nokogiri
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 4
46
+ - 0
47
+ version: 1.4.0
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: ruby-readability
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ - 2
61
+ - 3
62
+ version: 0.2.3
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: mocha
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ type: :development
77
+ version_requirements: *id004
78
+ description: Given a URL, retrieves thumbnail images (similar to when you share a link on Facebook or Digg).
79
+ email:
80
+ - toby.matejovsky@gmail.com
81
+ executables: []
82
+
83
+ extensions: []
84
+
85
+ extra_rdoc_files: []
86
+
87
+ files:
88
+ - .gitignore
89
+ - Gemfile
90
+ - README
91
+ - Rakefile
92
+ - lib/link_thumbnail.rb
93
+ - lib/link_thumbnail/version.rb
94
+ - lib/readability/document/get_best_candidate.rb
95
+ - link_thumbnail.gemspec
96
+ - test/fixtures/microformat.html
97
+ - test/fixtures/oembed.html
98
+ - test/fixtures/oembed_json.html
99
+ - test/fixtures/oembed_photo_response.json
100
+ - test/fixtures/oembed_photo_response.xml
101
+ - test/fixtures/oembed_thumbnail_response.json
102
+ - test/fixtures/oembed_thumbnail_response.xml
103
+ - test/fixtures/oembed_xml.html
104
+ - test/fixtures/open_graph.html
105
+ - test/fixtures/open_graph_bad_tag.html
106
+ - test/fixtures/open_graph_no_tag.html
107
+ - test/fixtures/semantic.html
108
+ - test/link_thumnail_test.rb
109
+ has_rdoc: true
110
+ homepage: https://github.com/tobym/link_thumbnail
111
+ licenses: []
112
+
113
+ post_install_message:
114
+ rdoc_options: []
115
+
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ segments:
132
+ - 0
133
+ version: "0"
134
+ requirements: []
135
+
136
+ rubyforge_project: link_thumbnail
137
+ rubygems_version: 1.3.7
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Retrieve thumbnail images for a given URL.
141
+ test_files:
142
+ - test/fixtures/microformat.html
143
+ - test/fixtures/oembed.html
144
+ - test/fixtures/oembed_json.html
145
+ - test/fixtures/oembed_photo_response.json
146
+ - test/fixtures/oembed_photo_response.xml
147
+ - test/fixtures/oembed_thumbnail_response.json
148
+ - test/fixtures/oembed_thumbnail_response.xml
149
+ - test/fixtures/oembed_xml.html
150
+ - test/fixtures/open_graph.html
151
+ - test/fixtures/open_graph_bad_tag.html
152
+ - test/fixtures/open_graph_no_tag.html
153
+ - test/fixtures/semantic.html
154
+ - test/link_thumnail_test.rb