link_thumbnailer 0.0.6 → 1.0.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/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Ruby gem generating image thumbnails from a given URL. Rank them and give you back an object containing images and website informations. Works like Facebook link previewer.
4
4
 
5
+ Demo Application is [here](https://github.com/gottfrois/link_thumbnailer_demo) !
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -26,6 +28,9 @@ This will add `link_thumbnailer.rb` to `config/initializers/`. See [#Configurati
26
28
 
27
29
  Run `irb` and require the gem:
28
30
 
31
+ require 'rails'
32
+ => true
33
+
29
34
  require 'link_thumbnailer'
30
35
  => true
31
36
 
@@ -64,14 +69,11 @@ Now with a regular website with no particular protocol:
64
69
  object.images.first.source_url
65
70
  => #<URI::HTTP:0x007ff7a923ef58 URL:http://foo.com/media/BAhbB1sHOgZmSSItMjAxMi8wNC8yNi8yMC8xMS80OS80MjYvY29yZG92YWJlYWNoLmpwZwY6BkVUWwg6BnA6CnRodW1iSSINNzUweDIwMCMGOwZU/cordovabeach.jpg>
66
71
 
67
- object.images.first.to_json
68
- => "{\"source_url\":\"http://foo.com/media/BAhbB1sHOgZmSSItMjAxMi8wNC8yNi8yMC8xMS80OS80MjYvY29yZG92YWJlYWNoLmpwZwY6BkVUWwg6BnA6CnRodW1iSSINNzUweDIwMCMGOwZU/cordovabeach.jpg\",\"mime_type\":\"image/jpeg\",\"density\":\"72x72\",\"rows\":200,\"filesize\":46501,\"number_colors\":9490}"
72
+ object.to_hash
73
+ => {"url"=>"http://foo.com", "images"=>[{:source_url=>"http://foo.com/media/BAhbB1sHOgZmSSItMjAxMi8wNC8yNi8yMC8xMS80OS80MjYvY29yZG92YWJlYWNoLmpwZwY6BkVUWwg6BnA6CnRodW1iSSINNzUweDIwMCMGOwZU/cordovabeach.jpg", :mime_type=>"image/jpeg", :rows=>200, :filesize=>46501, :number_colors=>9490}], "title"=>"Foo.com", "description"=>nil}
69
74
 
70
- object.images.first.to_a
71
- => {:source_url=>#<URI::HTTP:0x007f8a4a2561c0 URL:http://foo.com/media/BAhbB1sHOgZmSSItMjAxMi8wNC8yNi8yMC8xMS80OS80MjYvY29yZG92YWJlYWNoLmpwZwY6BkVUWwg6BnA6CnRodW1iSSINNzUweDIwMCMGOwZU/cordovabeach.jpg>, :mime_type=>"image/jpeg", :density=>"72x72", :rows=>200, :filesize=>46501, :number_colors=>9490}
72
-
73
- object.images.map(&:to_a)
74
- => [{:source_url=>#<URI::HTTP:0x007f8a4a2561c0 URL:http://foo.com/media/BAhbB1sHOgZmSSItMjAxMi8wNC8yNi8yMC8xMS80OS80MjYvY29yZG92YWJlYWNoLmpwZwY6BkVUWwg6BnA6CnRodW1iSSINNzUweDIwMCMGOwZU/cordovabeach.jpg>, :mime_type=>"image/jpeg", :density=>"72x72", :rows=>200, :filesize=>46501, :number_colors=>9490}]
75
+ object.to_json
76
+ => "{\"url\":\"http://foo.com\",\"images\":[{\"source_url\":\"http://foo.com/media/BAhbB1sHOgZmSSItMjAxMi8wNC8yNi8yMC8xMS80OS80MjYvY29yZG92YWJlYWNoLmpwZwY6BkVUWwg6BnA6CnRodW1iSSINNzUweDIwMCMGOwZU/cordovabeach.jpg\",\"mime_type\":\"image/jpeg\",\"rows\":200,\"filesize\":46501,\"number_colors\":9490}],\"title\":\"Foo.com\",\"description\":null}"
75
77
 
76
78
  You can check whether this object is valid or not (set mandatory attributes in the initializer, defaults are `[url, title, images]`)
77
79
 
@@ -81,6 +83,29 @@ You can check whether this object is valid or not (set mandatory attributes in t
81
83
  You also can set `limit` and `top` options at runtime:
82
84
 
83
85
  object = LinkThumbnailer.generate('http://foo.com', :top => 10, :limit => 20)
86
+
87
+ ## Preview Controller
88
+
89
+ For an easy integration into your application, use the builtin `PreviewController`.
90
+
91
+ Take a look at the demo application [here](https://github.com/gottfrois/link_thumbnailer_demo).
92
+
93
+ Basically, all you have to do in your view is something like this:
94
+
95
+ <%= form_tag '/link/preview', :method => 'post', :remote => true do %>
96
+ <%= text_field_tag :url %>
97
+ <%= submit_tag 'Preview' %>
98
+ <% end %>
99
+
100
+ Don't forget to add this anywhere in your `routes.rb` file:
101
+
102
+ use_link_thumbnailer
103
+
104
+ Note: You won't have to bother with this if you did runned the installer using:
105
+
106
+ $ rails g link_thumbnailer:install
107
+
108
+ The `PreviewController` will automatically respond to json calls, returning json version of the preview object. Just like in the IRB console above.
84
109
 
85
110
  ## Configuration
86
111
 
@@ -120,6 +145,7 @@ Implemented:
120
145
  - Find images and sort them according to how well they represent what the page is about (includes absolute images).
121
146
  - Sort images based on their size and color.
122
147
  - Blacklist some well known advertisings image urls.
148
+ - Routes and Controllers to handle preview generation
123
149
 
124
150
  Coming soon:
125
151
 
@@ -0,0 +1,4 @@
1
+ module LinkThumbnailer
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ module LinkThumbnailer
2
+ class PreviewsController < ApplicationController
3
+
4
+ respond_to :json
5
+
6
+ def create
7
+ @preview = LinkThumbnailer.generate(params[:url])
8
+ render :json => @preview.to_json
9
+ end
10
+ end
11
+ end
@@ -6,6 +6,10 @@ module LinkThumbnailer
6
6
 
7
7
  desc 'Creates a LinkThumbnailer initializer for your application.'
8
8
 
9
+ def install
10
+ route "use_link_thumbnailer"
11
+ end
12
+
9
13
  def copy_initializer
10
14
  template 'initializer.rb', 'config/initializers/link_thumbnailer.rb'
11
15
  end
@@ -18,6 +18,12 @@ LinkThumbnailer.configure do |config|
18
18
  # %r{^http://s7\.addthis\.com/}
19
19
  # ]
20
20
 
21
+ # Included Rmagick attributes for images. See http://www.imagemagick.org/RMagick/doc/
22
+ # for more details.
23
+ # 'source_url' is a custom attribute and should always be included since this
24
+ # is where you'll find the image url.
25
+ # config.rmagick_attributes = %w(source_url mime_type colums rows filesize number_colors)
26
+
21
27
  # Fetch 10 images maximum.
22
28
  # config.limit = 10
23
29
 
@@ -0,0 +1,9 @@
1
+ module LinkThumbnailer
2
+ class Engine < Rails::Engine
3
+
4
+ initializer 'link_thumbnailer.routes' do
5
+ LinkThumbnailer::Rails::Routes.install!
6
+ end
7
+
8
+ end
9
+ end
@@ -1,4 +1,5 @@
1
1
  require 'hashie'
2
+ require 'json'
2
3
 
3
4
  module LinkThumbnailer
4
5
  class Object < Hashie::Mash
@@ -20,5 +21,21 @@ module LinkThumbnailer
20
21
  true
21
22
  end
22
23
 
24
+ def to_hash
25
+ if self.images.none? {|i| i.is_a?(String)}
26
+ super.merge('images' => self.images.map(&:to_hash))
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ def to_json
33
+ if self.images.none? {|i| i.is_a?(String)}
34
+ JSON.generate(self.to_hash.merge('images' => self.images.map(&:to_hash)))
35
+ else
36
+ JSON.generate(self.to_hash)
37
+ end
38
+ end
39
+
23
40
  end
24
41
  end
@@ -7,7 +7,11 @@ module LinkThumbnailer
7
7
  object[$1.gsub('-', '_')] = m.attribute('content').to_s
8
8
  end
9
9
  end
10
- object[:images] = [object[:image]] if object[:image]
10
+
11
+ object[:images] = []
12
+ if object[:image]
13
+ object[:images] << { :source_url => object[:image] }
14
+ end
11
15
 
12
16
  object
13
17
  end
@@ -0,0 +1,30 @@
1
+ module LinkThumbnailer
2
+ module Rails
3
+ class Routes
4
+ class Mapper
5
+
6
+ def initialize(mapping = Mapping.new)
7
+ @mapping = mapping
8
+ end
9
+
10
+ def map(&block)
11
+ self.instance_eval(&block) if block
12
+ @mapping
13
+ end
14
+
15
+ def controllers(controller_names = {})
16
+ @mapping.controllers.merge!(controller_names)
17
+ end
18
+
19
+ def skip_controllers(*controller_names)
20
+ @mapping.skips = controller_names
21
+ end
22
+
23
+ def as(alias_names = {})
24
+ @mapping.as.merge!(alias_names)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ module LinkThumbnailer
2
+ module Rails
3
+ class Routes
4
+ class Mapping
5
+
6
+ attr_accessor :controllers, :as, :skips
7
+
8
+ def initialize
9
+ @controllers = {
10
+ :previews => 'link_thumbnailer/previews'
11
+ }
12
+
13
+ @as = {
14
+ :previews => :preview
15
+ }
16
+
17
+ @skips = []
18
+ end
19
+
20
+ def [](routes)
21
+ {
22
+ :controllers => @controllers[routes],
23
+ :as => @as[routes]
24
+ }
25
+ end
26
+
27
+ def skipped?(controller)
28
+ return @skips.include?(controller)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,47 @@
1
+ require 'link_thumbnailer/rails/routes/mapping'
2
+ require 'link_thumbnailer/rails/routes/mapper'
3
+
4
+ module LinkThumbnailer
5
+ module Rails
6
+ class Routes
7
+
8
+ module Helper
9
+ def use_link_thumbnailer(options = {}, &block)
10
+ LinkThumbnailer::Rails::Routes.new(self, &block).generate_routes!(options)
11
+ end
12
+ end
13
+
14
+ def self.install!
15
+ ActionDispatch::Routing::Mapper.send :include, LinkThumbnailer::Rails::Routes::Helper
16
+ end
17
+
18
+ attr_accessor :routes
19
+
20
+ def initialize(routes, &options)
21
+ @routes, @options = routes, options
22
+ end
23
+
24
+ def generate_routes!(options)
25
+ @mapping = Mapper.new.map(&@options)
26
+ routes.scope 'link', :as => 'link' do
27
+ map_route(:previews, :preview_routes)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def map_route(name, method)
34
+ unless @mapping.skipped?(name)
35
+ send method, @mapping[name]
36
+ end
37
+ end
38
+
39
+ def preview_routes(mapping)
40
+ routes.scope :controller => mapping[:controllers] do
41
+ routes.match 'preview', :via => :post, :action => :create, :as => mapping[:as], :defaults => { :format => 'json' }
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module LinkThumbnailer
2
- VERSION = "0.0.6"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,22 +1,18 @@
1
- require 'json'
2
-
3
1
  module LinkThumbnailer
4
2
  module WebImage
5
3
 
6
4
  attr_accessor :source_url, :doc
7
5
 
8
- def to_a
6
+ def to_hash
9
7
  result = {}
10
- %w(source_url mime_type density colums rows filesize number_colors).each {|m|
11
- result[m.to_sym] = self.send(m) if self.respond_to?(m)
8
+ LinkThumbnailer.configuration.rmagick_attributes.each {|m|
9
+ k = m.to_sym
10
+ result[k] = self.send(m) if self.respond_to?(m)
11
+ result[k] = result[k].to_s if result[k].is_a?(URI)
12
12
  }
13
13
 
14
14
  result
15
15
  end
16
16
 
17
- def to_json
18
- JSON(self.to_a)
19
- end
20
-
21
17
  end
22
18
  end
@@ -1,3 +1,4 @@
1
+ require 'link_thumbnailer/engine' if defined? Rails
1
2
  require 'link_thumbnailer/config'
2
3
  require 'link_thumbnailer/object'
3
4
  require 'link_thumbnailer/fetcher'
@@ -7,13 +8,15 @@ require 'link_thumbnailer/img_url_filter'
7
8
  require 'link_thumbnailer/img_parser'
8
9
  require 'link_thumbnailer/img_comparator'
9
10
  require 'link_thumbnailer/web_image'
10
-
11
11
  require 'link_thumbnailer/opengraph'
12
-
13
12
  require 'link_thumbnailer/version'
14
13
 
15
14
  module LinkThumbnailer
16
15
 
16
+ module Rails
17
+ autoload :Routes, 'link_thumbnailer/rails/routes'
18
+ end
19
+
17
20
  class << self
18
21
 
19
22
  attr_accessor :configuration, :object, :fetcher, :doc_parser,
@@ -30,6 +33,7 @@ module LinkThumbnailer
30
33
  %r{^http://pixel\.quantserve\.com/},
31
34
  %r{^http://s7\.addthis\.com/}
32
35
  ],
36
+ :rmagick_attributes => %w(source_url mime_type colums rows filesize number_colors),
33
37
  :limit => 10,
34
38
  :top => 5
35
39
  )
@@ -48,6 +52,8 @@ module LinkThumbnailer
48
52
  self.object = LinkThumbnailer::Object.new
49
53
  self.fetcher = LinkThumbnailer::Fetcher.new
50
54
  self.doc_parser = LinkThumbnailer::DocParser.new
55
+ self.img_url_filters = [LinkThumbnailer::ImgUrlFilter.new]
56
+ self.img_parser = LinkThumbnailer::ImgParser.new(self.fetcher, self.img_url_filters)
51
57
 
52
58
  doc_string = self.fetcher.fetch(url)
53
59
  doc = self.doc_parser.parse(doc_string, url)
@@ -56,11 +62,10 @@ module LinkThumbnailer
56
62
 
57
63
  # Try Opengraph first
58
64
  self.object = LinkThumbnailer::Opengraph.parse(self.object, doc)
65
+
59
66
  return self.object if self.object.valid?
60
67
 
61
68
  # Else try manually
62
- self.img_url_filters = [LinkThumbnailer::ImgUrlFilter.new]
63
- self.img_parser = LinkThumbnailer::ImgParser.new(self.fetcher, self.img_url_filters)
64
69
 
65
70
  self.object[:title] = doc.title
66
71
  self.object[:description] = doc.description
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.add_dependency(%q{hashie}, ['~> 1.2.0'])
20
20
  gem.add_dependency(%q{net-http-persistent}, ['~> 2.7'])
21
21
  gem.add_dependency(%q{rmagick}, ['~> 2.13.1'])
22
- gem.add_dependency(%q{json}, ['~> 1.7.5'])
22
+ gem.add_dependency(%q{json}, ['~> 1.7.6'])
23
23
 
24
24
  gem.add_development_dependency(%q{rspec}, ['~> 2.11.0'])
25
25
  gem.add_development_dependency(%q{webmock}, ['~> 1.8.10'])
@@ -25,6 +25,7 @@ describe LinkThumbnailer do
25
25
  config.strict = false
26
26
  config.redirect_limit = 5
27
27
  config.blacklist_urls = []
28
+ config.rmagick_attributes = []
28
29
  config.limit = 5
29
30
  config.top = 10
30
31
  }
@@ -38,6 +39,7 @@ describe LinkThumbnailer do
38
39
  specify { LinkThumbnailer.configuration.strict.should be_false }
39
40
  specify { LinkThumbnailer.configuration.redirect_limit.should eq(5) }
40
41
  specify { LinkThumbnailer.configuration.blacklist_urls.should eq([]) }
42
+ specify { LinkThumbnailer.configuration.rmagick_attributes.should eq([]) }
41
43
  specify { LinkThumbnailer.configuration.limit.should eq(5) }
42
44
  specify { LinkThumbnailer.configuration.top.should eq(10) }
43
45
 
@@ -60,6 +62,7 @@ describe LinkThumbnailer do
60
62
  %r{^http://pixel\.quantserve\.com/},
61
63
  %r{^http://s7\.addthis\.com/}
62
64
  ]) }
65
+ specify { LinkThumbnailer.configuration.rmagick_attributes.should eq(%w(source_url mime_type colums rows filesize number_colors)) }
63
66
  specify { LinkThumbnailer.configuration.limit.should eq(10) }
64
67
  specify { LinkThumbnailer.configuration.top.should eq(5) }
65
68
 
data/spec/object_spec.rb CHANGED
@@ -3,6 +3,8 @@ require 'spec_helper'
3
3
  describe LinkThumbnailer::Object do
4
4
 
5
5
  it { should respond_to :valid? }
6
+ it { should respond_to :to_hash }
7
+ it { should respond_to :to_json }
6
8
 
7
9
  let(:object) { LinkThumbnailer::Object.new }
8
10
 
@@ -92,4 +94,37 @@ describe LinkThumbnailer::Object do
92
94
 
93
95
  end
94
96
 
97
+ context "dealing with WebImage module" do
98
+
99
+ class Foo
100
+ end
101
+
102
+ let(:foo) { Foo.new }
103
+
104
+ before do
105
+ foo.extend LinkThumbnailer::WebImage
106
+ object['images'] = [foo]
107
+ end
108
+
109
+ describe ".to_hash" do
110
+
111
+ subject { object.to_hash }
112
+
113
+ it { subject.is_a?(Hash).should be_true }
114
+ it { should include('images') }
115
+ it { subject['images'].is_a?(Array).should be_true }
116
+
117
+ end
118
+
119
+ describe ".to_json" do
120
+
121
+ subject { object.to_json }
122
+
123
+ it { subject.is_a?(String).should be_true }
124
+ it { should include('images') }
125
+
126
+ end
127
+
128
+ end
129
+
95
130
  end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'rspec'
2
2
  require 'webmock/rspec'
3
+ require 'json'
3
4
 
4
5
  require 'link_thumbnailer'
5
6
 
6
7
  RSpec.configure do |config|
8
+ config.mock_with :rspec
7
9
  end
@@ -13,26 +13,25 @@ describe LinkThumbnailer::WebImage do
13
13
 
14
14
  subject { foo }
15
15
 
16
- it { should respond_to :to_a }
17
- it { should respond_to :to_json }
16
+ it { should respond_to :to_hash }
18
17
  it { should respond_to :source_url }
19
18
  it { should respond_to :doc }
20
19
 
21
- describe ".to_a" do
20
+ describe ".to_hash" do
22
21
 
23
22
  context "with default attributes" do
24
23
 
25
24
  let(:attributes) { [:source_url] }
26
25
 
27
- subject { foo.to_a }
26
+ subject { foo.to_hash }
28
27
 
29
- it { subject.keys.should eq(attributes) }
28
+ it { subject.keys.should eq(attributes.map(&:to_sym)) }
30
29
 
31
30
  end
32
31
 
33
32
  context "with all attributes" do
34
33
 
35
- let(:attributes) { [:source_url, :mime_type, :density, :colums, :rows, :filesize, :number_colors] }
34
+ let(:attributes) { LinkThumbnailer.configuration.rmagick_attributes }
36
35
 
37
36
  before do
38
37
  attributes.each {|a| foo.class.send(:define_method, a.to_sym) { 'foo' } }
@@ -42,46 +41,13 @@ describe LinkThumbnailer::WebImage do
42
41
  attributes.each {|a| foo.class.send(:undef_method, a.to_sym) }
43
42
  end
44
43
 
45
- subject { foo.to_a }
44
+ subject { foo.to_hash }
46
45
 
47
- it { subject.keys.should eq(attributes) }
46
+ it { subject.keys.should eq(attributes.map(&:to_sym)) }
48
47
  it { subject.values.should include('foo') }
49
48
 
50
49
  end
51
50
 
52
51
  end
53
52
 
54
- describe ".to_json" do
55
-
56
- context "with default attributes" do
57
-
58
- let(:attributes) { [:source_url] }
59
-
60
- subject { foo.to_json }
61
-
62
- it { JSON.parse(subject).keys.map(&:to_sym).should eq(attributes) }
63
-
64
- end
65
-
66
- context "with all attributes" do
67
-
68
- let(:attributes) { [:source_url, :mime_type, :density, :colums, :rows, :filesize, :number_colors] }
69
-
70
- before do
71
- attributes.each {|a| foo.class.send(:define_method, a.to_sym) { 'foo' } }
72
- end
73
-
74
- after do
75
- attributes.each {|a| foo.class.send(:undef_method, a.to_sym) }
76
- end
77
-
78
- subject { foo.to_json }
79
-
80
- it { JSON.parse(subject).keys.map(&:to_sym).should eq(attributes) }
81
- it { JSON.parse(subject).values.should include('foo') }
82
-
83
- end
84
-
85
- end
86
-
87
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: link_thumbnailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-27 00:00:00.000000000 Z
12
+ date: 2012-12-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -82,7 +82,7 @@ dependencies:
82
82
  requirements:
83
83
  - - ~>
84
84
  - !ruby/object:Gem::Version
85
- version: 1.7.5
85
+ version: 1.7.6
86
86
  type: :runtime
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,7 +90,7 @@ dependencies:
90
90
  requirements:
91
91
  - - ~>
92
92
  - !ruby/object:Gem::Version
93
- version: 1.7.5
93
+ version: 1.7.6
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: rspec
96
96
  requirement: !ruby/object:Gem::Requirement
@@ -137,18 +137,24 @@ files:
137
137
  - LICENSE
138
138
  - README.md
139
139
  - Rakefile
140
+ - app/controllers/link_thumbnailer/application_controller.rb
141
+ - app/controllers/link_thumbnailer/previews_controller.rb
140
142
  - lib/generators/link_thumbnailer/install_generator.rb
141
143
  - lib/generators/templates/initializer.rb
142
144
  - lib/link_thumbnailer.rb
143
145
  - lib/link_thumbnailer/config.rb
144
146
  - lib/link_thumbnailer/doc.rb
145
147
  - lib/link_thumbnailer/doc_parser.rb
148
+ - lib/link_thumbnailer/engine.rb
146
149
  - lib/link_thumbnailer/fetcher.rb
147
150
  - lib/link_thumbnailer/img_comparator.rb
148
151
  - lib/link_thumbnailer/img_parser.rb
149
152
  - lib/link_thumbnailer/img_url_filter.rb
150
153
  - lib/link_thumbnailer/object.rb
151
154
  - lib/link_thumbnailer/opengraph.rb
155
+ - lib/link_thumbnailer/rails/routes.rb
156
+ - lib/link_thumbnailer/rails/routes/mapper.rb
157
+ - lib/link_thumbnailer/rails/routes/mapping.rb
152
158
  - lib/link_thumbnailer/version.rb
153
159
  - lib/link_thumbnailer/web_image.rb
154
160
  - link_thumbnailer.gemspec