faviconduit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +65 -0
  5. data/Rakefile +30 -0
  6. data/VERSION +1 -0
  7. data/faviconduit.gemspec +121 -0
  8. data/lib/faviconduit.rb +54 -0
  9. data/lib/runner.rb +28 -0
  10. data/test/helper.rb +11 -0
  11. data/test/rails_root/.gitignore +2 -0
  12. data/test/rails_root/Gemfile +29 -0
  13. data/test/rails_root/Gemfile.lock +71 -0
  14. data/test/rails_root/README +256 -0
  15. data/test/rails_root/Rakefile +7 -0
  16. data/test/rails_root/app/controllers/application_controller.rb +3 -0
  17. data/test/rails_root/app/controllers/welcome_controller.rb +8 -0
  18. data/test/rails_root/app/helpers/application_helper.rb +2 -0
  19. data/test/rails_root/app/helpers/welcome_helper.rb +2 -0
  20. data/test/rails_root/app/views/layouts/application.html.erb +14 -0
  21. data/test/rails_root/app/views/welcome/default.html.erb +3 -0
  22. data/test/rails_root/app/views/welcome/html.html.erb +19 -0
  23. data/test/rails_root/app/views/welcome/icon.html.erb +18 -0
  24. data/test/rails_root/app/views/welcome/missing.html.erb +18 -0
  25. data/test/rails_root/app/views/welcome/shortcut_icon.html.erb +18 -0
  26. data/test/rails_root/app/views/welcome/zero.html.erb +18 -0
  27. data/test/rails_root/config.ru +4 -0
  28. data/test/rails_root/config/application.rb +47 -0
  29. data/test/rails_root/config/boot.rb +13 -0
  30. data/test/rails_root/config/environment.rb +5 -0
  31. data/test/rails_root/config/environments/development.rb +26 -0
  32. data/test/rails_root/config/environments/production.rb +49 -0
  33. data/test/rails_root/config/environments/test.rb +35 -0
  34. data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  35. data/test/rails_root/config/initializers/inflections.rb +10 -0
  36. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  37. data/test/rails_root/config/initializers/secret_token.rb +7 -0
  38. data/test/rails_root/config/initializers/session_store.rb +8 -0
  39. data/test/rails_root/config/locales/en.yml +5 -0
  40. data/test/rails_root/config/routes.rb +61 -0
  41. data/test/rails_root/db/seeds.rb +7 -0
  42. data/test/rails_root/doc/README_FOR_APP +2 -0
  43. data/test/rails_root/public/404.html +26 -0
  44. data/test/rails_root/public/422.html +26 -0
  45. data/test/rails_root/public/500.html +26 -0
  46. data/test/rails_root/public/favicon.ico +0 -0
  47. data/test/rails_root/public/images/favicon_valid.ico +0 -0
  48. data/test/rails_root/public/images/favicon_zero.ico +0 -0
  49. data/test/rails_root/public/images/rails.png +0 -0
  50. data/test/rails_root/public/javascripts/application.js +0 -0
  51. data/test/rails_root/public/robots.txt +5 -0
  52. data/test/rails_root/script/rails +6 -0
  53. data/test/rails_root/test/functional/welcome_controller_test.rb +9 -0
  54. data/test/rails_root/test/unit/helpers/welcome_helper_test.rb +4 -0
  55. data/test/test_faviconduit.rb +108 -0
  56. metadata +164 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Kevin Swope
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,65 @@
1
+ = faviconduit
2
+
3
+ Attempts to download a URL's favicon.
4
+
5
+ == Synopsis
6
+
7
+ raise "url missing" unless uri = ARGV[0]
8
+
9
+ begin
10
+
11
+ fav = Faviconduit.get(uri)
12
+
13
+ puts "found favicon at #{fav.url}"
14
+
15
+ File.open('favicon.ico', 'w') do |file|
16
+ file.write(fav.data)
17
+ end
18
+
19
+ rescue Faviconduit::MissingFavicon
20
+
21
+ puts "favicon missing"
22
+
23
+ rescue Faviconduit::InvalidFavicon
24
+
25
+ puts "favicon invalid"
26
+
27
+ end
28
+
29
+ == Methods
30
+
31
+ Faviconduit.get(uri)
32
+
33
+ Takes a url and attempts to returns the favicon object. The url can be
34
+ fairly loosely specified because Addressable::URI.heuristic_parse is
35
+ used to figure it out.
36
+
37
+ obj.url
38
+
39
+ The favicon url it was ultimately found at.
40
+
41
+ obj.data
42
+
43
+ The favicon image data.
44
+
45
+ == Exceptions
46
+
47
+ Faviconduit::MissingFavicon
48
+
49
+ Raises this if the favicon simply isn't found.
50
+
51
+ Faviconduit::InvalidFavicon
52
+
53
+ Raises this if the favicon is determined to be not a valid favicon.
54
+ Currently (0.1) determins this if the content-type is not /^image/
55
+ or the size is 0 bytes.
56
+
57
+ Faviconduit::Error
58
+
59
+ This is the parent of all faviconduit exceptions and can be caught
60
+ instead of the more specific exceptions.
61
+
62
+
63
+ == Copyright
64
+
65
+ Copyright (c) 2010 Kevin Swope. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ desc = "download a webpage's favicon"
8
+ gem.name = "faviconduit"
9
+ gem.summary = desc
10
+ gem.description = desc
11
+ gem.email = "git-kevdev@snkmail.com"
12
+ gem.homepage = "http://github.com/kswope/faviconduit"
13
+ gem.authors = ["Kevin Swope"]
14
+ gem.add_dependency 'nokogiri'
15
+ gem.add_dependency 'addressable'
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ task :default => :test
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,121 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{faviconduit}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kevin Swope"]
12
+ s.date = %q{2010-10-22}
13
+ s.description = %q{download a webpage's favicon}
14
+ s.email = %q{git-kevdev@snkmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "faviconduit.gemspec",
27
+ "lib/faviconduit.rb",
28
+ "lib/runner.rb",
29
+ "test/helper.rb",
30
+ "test/rails_root/.gitignore",
31
+ "test/rails_root/Gemfile",
32
+ "test/rails_root/Gemfile.lock",
33
+ "test/rails_root/README",
34
+ "test/rails_root/Rakefile",
35
+ "test/rails_root/app/controllers/application_controller.rb",
36
+ "test/rails_root/app/controllers/welcome_controller.rb",
37
+ "test/rails_root/app/helpers/application_helper.rb",
38
+ "test/rails_root/app/helpers/welcome_helper.rb",
39
+ "test/rails_root/app/views/layouts/application.html.erb",
40
+ "test/rails_root/app/views/welcome/default.html.erb",
41
+ "test/rails_root/app/views/welcome/html.html.erb",
42
+ "test/rails_root/app/views/welcome/icon.html.erb",
43
+ "test/rails_root/app/views/welcome/missing.html.erb",
44
+ "test/rails_root/app/views/welcome/shortcut_icon.html.erb",
45
+ "test/rails_root/app/views/welcome/zero.html.erb",
46
+ "test/rails_root/config.ru",
47
+ "test/rails_root/config/application.rb",
48
+ "test/rails_root/config/boot.rb",
49
+ "test/rails_root/config/environment.rb",
50
+ "test/rails_root/config/environments/development.rb",
51
+ "test/rails_root/config/environments/production.rb",
52
+ "test/rails_root/config/environments/test.rb",
53
+ "test/rails_root/config/initializers/backtrace_silencers.rb",
54
+ "test/rails_root/config/initializers/inflections.rb",
55
+ "test/rails_root/config/initializers/mime_types.rb",
56
+ "test/rails_root/config/initializers/secret_token.rb",
57
+ "test/rails_root/config/initializers/session_store.rb",
58
+ "test/rails_root/config/locales/en.yml",
59
+ "test/rails_root/config/routes.rb",
60
+ "test/rails_root/db/seeds.rb",
61
+ "test/rails_root/doc/README_FOR_APP",
62
+ "test/rails_root/public/404.html",
63
+ "test/rails_root/public/422.html",
64
+ "test/rails_root/public/500.html",
65
+ "test/rails_root/public/favicon.ico",
66
+ "test/rails_root/public/images/favicon_valid.ico",
67
+ "test/rails_root/public/images/favicon_zero.ico",
68
+ "test/rails_root/public/images/rails.png",
69
+ "test/rails_root/public/javascripts/application.js",
70
+ "test/rails_root/public/robots.txt",
71
+ "test/rails_root/script/rails",
72
+ "test/rails_root/test/functional/welcome_controller_test.rb",
73
+ "test/rails_root/test/unit/helpers/welcome_helper_test.rb",
74
+ "test/test_faviconduit.rb"
75
+ ]
76
+ s.homepage = %q{http://github.com/kswope/faviconduit}
77
+ s.rdoc_options = ["--charset=UTF-8"]
78
+ s.require_paths = ["lib"]
79
+ s.rubygems_version = %q{1.3.7}
80
+ s.summary = %q{download a webpage's favicon}
81
+ s.test_files = [
82
+ "test/helper.rb",
83
+ "test/rails_root/app/controllers/application_controller.rb",
84
+ "test/rails_root/app/controllers/welcome_controller.rb",
85
+ "test/rails_root/app/helpers/application_helper.rb",
86
+ "test/rails_root/app/helpers/welcome_helper.rb",
87
+ "test/rails_root/config/application.rb",
88
+ "test/rails_root/config/boot.rb",
89
+ "test/rails_root/config/environment.rb",
90
+ "test/rails_root/config/environments/development.rb",
91
+ "test/rails_root/config/environments/production.rb",
92
+ "test/rails_root/config/environments/test.rb",
93
+ "test/rails_root/config/initializers/backtrace_silencers.rb",
94
+ "test/rails_root/config/initializers/inflections.rb",
95
+ "test/rails_root/config/initializers/mime_types.rb",
96
+ "test/rails_root/config/initializers/secret_token.rb",
97
+ "test/rails_root/config/initializers/session_store.rb",
98
+ "test/rails_root/config/routes.rb",
99
+ "test/rails_root/db/seeds.rb",
100
+ "test/rails_root/test/functional/welcome_controller_test.rb",
101
+ "test/rails_root/test/unit/helpers/welcome_helper_test.rb",
102
+ "test/test_faviconduit.rb"
103
+ ]
104
+
105
+ if s.respond_to? :specification_version then
106
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
107
+ s.specification_version = 3
108
+
109
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
110
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
111
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
112
+ else
113
+ s.add_dependency(%q<nokogiri>, [">= 0"])
114
+ s.add_dependency(%q<addressable>, [">= 0"])
115
+ end
116
+ else
117
+ s.add_dependency(%q<nokogiri>, [">= 0"])
118
+ s.add_dependency(%q<addressable>, [">= 0"])
119
+ end
120
+ end
121
+
@@ -0,0 +1,54 @@
1
+
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+ require "addressable/uri"
5
+
6
+
7
+ module Faviconduit
8
+
9
+ class Error < StandardError; end
10
+ class InvalidFavicon < Error; end
11
+ class MissingFavicon < Error; end
12
+
13
+ class Favicon; attr_accessor :url, :data end
14
+
15
+
16
+ def self.get(url)
17
+
18
+ uri = Addressable::URI.heuristic_parse(url)
19
+ uri = Addressable::URI.encode(uri) # needed for chars with accents in url
20
+
21
+ doc = Nokogiri::HTML(open(uri))
22
+
23
+ path = doc.xpath("//link[@rel='shortcut icon' or @rel='icon']/@href").first
24
+ path = path ? path.to_s : '/favicon.ico'
25
+
26
+ fav_uri = Addressable::URI.join(uri, path.to_s)
27
+
28
+ begin
29
+
30
+ stream = open(fav_uri)
31
+
32
+ unless stream.content_type[/^image/]
33
+ raise(InvalidFavicon, "wrong content_type (#{stream.content_type})")
34
+ end
35
+
36
+ data = stream.read
37
+
38
+ if data.size == 0
39
+ raise(InvalidFavicon, "zero data")
40
+ end
41
+
42
+ fav = Favicon.new
43
+ fav.url = fav_uri.to_s
44
+ fav.data = data
45
+ return fav
46
+
47
+ rescue OpenURI::HTTPError => e
48
+ raise MissingFavicon if e.to_s[/404/]
49
+ raise # nevermind, reraise the previous exception
50
+ end
51
+
52
+ end
53
+
54
+ end
data/lib/runner.rb ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require './faviconduit'
4
+
5
+ # just a little script to run the library
6
+
7
+ # download favicons like this...
8
+ # shell> ./runner.rb slashdot.org
9
+
10
+
11
+ raise "url missing" unless uri = ARGV[0]
12
+
13
+ begin
14
+
15
+ fav = Faviconduit.get(uri)
16
+
17
+ File.open('favicon.ico', 'w') do |file|
18
+ puts "writing #{fav.url}";
19
+ file.write(fav.data)
20
+ end
21
+
22
+ rescue Faviconduit::MissingFavicon
23
+ puts "favicon missing"
24
+ rescue Faviconduit::InvalidFavicon
25
+ puts "favicon invalid"
26
+ end
27
+
28
+
data/test/helper.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'faviconduit'
7
+
8
+ class Test::Unit::TestCase
9
+ end
10
+
11
+ require "addressable/uri"
@@ -0,0 +1,2 @@
1
+ log/*
2
+ tmp/*
@@ -0,0 +1,29 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rails', '3.0.0'
4
+
5
+ # Bundle edge Rails instead:
6
+ # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
+
8
+
9
+ # Use unicorn as the web server
10
+ # gem 'unicorn'
11
+
12
+ # Deploy with Capistrano
13
+ # gem 'capistrano'
14
+
15
+ # To use debugger
16
+ # gem 'ruby-debug'
17
+
18
+ # Bundle the extra gems:
19
+ # gem 'bj'
20
+ # gem 'nokogiri'
21
+ # gem 'sqlite3-ruby', :require => 'sqlite3'
22
+ # gem 'aws-s3', :require => 'aws/s3'
23
+
24
+ # Bundle gems for the local environment. Make sure to
25
+ # put test-only gems in this group so their generators
26
+ # and rake tasks are available in development mode:
27
+ # group :development, :test do
28
+ # gem 'webrat'
29
+ # end
@@ -0,0 +1,71 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionmailer (3.0.0)
6
+ actionpack (= 3.0.0)
7
+ mail (~> 2.2.5)
8
+ actionpack (3.0.0)
9
+ activemodel (= 3.0.0)
10
+ activesupport (= 3.0.0)
11
+ builder (~> 2.1.2)
12
+ erubis (~> 2.6.6)
13
+ i18n (~> 0.4.1)
14
+ rack (~> 1.2.1)
15
+ rack-mount (~> 0.6.12)
16
+ rack-test (~> 0.5.4)
17
+ tzinfo (~> 0.3.23)
18
+ activemodel (3.0.0)
19
+ activesupport (= 3.0.0)
20
+ builder (~> 2.1.2)
21
+ i18n (~> 0.4.1)
22
+ activerecord (3.0.0)
23
+ activemodel (= 3.0.0)
24
+ activesupport (= 3.0.0)
25
+ arel (~> 1.0.0)
26
+ tzinfo (~> 0.3.23)
27
+ activeresource (3.0.0)
28
+ activemodel (= 3.0.0)
29
+ activesupport (= 3.0.0)
30
+ activesupport (3.0.0)
31
+ arel (1.0.1)
32
+ activesupport (~> 3.0.0)
33
+ builder (2.1.2)
34
+ erubis (2.6.6)
35
+ abstract (>= 1.0.0)
36
+ i18n (0.4.1)
37
+ mail (2.2.7)
38
+ activesupport (>= 2.3.6)
39
+ mime-types
40
+ treetop (>= 1.4.5)
41
+ mime-types (1.16)
42
+ polyglot (0.3.1)
43
+ rack (1.2.1)
44
+ rack-mount (0.6.13)
45
+ rack (>= 1.0.0)
46
+ rack-test (0.5.6)
47
+ rack (>= 1.0)
48
+ rails (3.0.0)
49
+ actionmailer (= 3.0.0)
50
+ actionpack (= 3.0.0)
51
+ activerecord (= 3.0.0)
52
+ activeresource (= 3.0.0)
53
+ activesupport (= 3.0.0)
54
+ bundler (~> 1.0.0)
55
+ railties (= 3.0.0)
56
+ railties (3.0.0)
57
+ actionpack (= 3.0.0)
58
+ activesupport (= 3.0.0)
59
+ rake (>= 0.8.4)
60
+ thor (~> 0.14.0)
61
+ rake (0.8.7)
62
+ thor (0.14.3)
63
+ treetop (1.4.8)
64
+ polyglot (>= 0.3.1)
65
+ tzinfo (0.3.23)
66
+
67
+ PLATFORMS
68
+ ruby
69
+
70
+ DEPENDENCIES
71
+ rails (= 3.0.0)