browsernizer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ .rvmrc
2
+ .rspec
3
+ *.gem
4
+ .bundle
5
+ Gemfile.lock
6
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in browsernizer.gemspec
4
+ gemspec
@@ -0,0 +1,53 @@
1
+ # Browsernizer
2
+
3
+ Want friendly "please upgrade your browser" page? This gem is for you.
4
+
5
+ You can redirect your visitors to any page you like (static or dynamic).
6
+ Just specify `config.location` option in initializer file.
7
+
8
+
9
+ ## Installation
10
+
11
+ Add following line to your `Gemfile`:
12
+
13
+ gem 'browsernizer'
14
+
15
+ Hook it up:
16
+
17
+ rails generate browsernizer:install
18
+
19
+ Configure browser support in `config/initializers/browsernizer.rb` file.
20
+
21
+ All browsers that are not listed in initializer file will be considered to be **supported**.
22
+
23
+
24
+ ## Browsers
25
+
26
+ You should specify browser name as a string. Here are the available options:
27
+
28
+ * Chrome
29
+ * Firefox
30
+ * Safari
31
+ * Opera
32
+ * Internet Explorer
33
+
34
+ And some less popular:
35
+
36
+ * Android
37
+ * webOS
38
+ * BlackBerry
39
+ * Symbian
40
+ * Camino
41
+ * Iceweasel
42
+ * Seamonkey
43
+
44
+ Browser detection is done using [useragent gem](https://github.com/josh/useragent).
45
+
46
+
47
+
48
+ ## Credits and License
49
+
50
+ Developed by Milovan Zogovic.
51
+
52
+ I don't believe in licenses and other woody crap.
53
+ Do whatever you want with this :)
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :default => :spec
5
+
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.ruby_opts = ["-w"]
8
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "browsernizer/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "browsernizer"
7
+ s.version = Browsernizer::VERSION
8
+ s.authors = ["Milovan Zogovic"]
9
+ s.email = ["milovan.zogovic@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Want friendly "please upgrade your browser" page? This gem is for you.}
12
+ s.description = %q{Rack middleware for redirecting unsupported user agents to "please upgrade" page}
13
+
14
+ s.rubyforge_project = "browsernizer"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rake"
22
+ s.add_development_dependency "rspec"
23
+
24
+ s.add_runtime_dependency 'useragent', "~> 0.4.6"
25
+ end
@@ -0,0 +1,13 @@
1
+ #TODO: remove when useragent gem is fixed
2
+ require 'rubygems'
3
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
4
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
+
6
+
7
+ require "browsernizer/browser"
8
+ require "browsernizer/browser_version"
9
+ require "browsernizer/config"
10
+ require "browsernizer/router"
11
+ require "browsernizer/version"
12
+
13
+ require 'useragent'
@@ -0,0 +1,6 @@
1
+ module Browsernizer
2
+
3
+ class Browser < Struct.new(:browser, :version)
4
+ end
5
+
6
+ end
@@ -0,0 +1,24 @@
1
+ module Browsernizer
2
+ class BrowserVersion
3
+ include ::Comparable
4
+
5
+ attr_accessor :to_a
6
+
7
+ def initialize(version)
8
+ @version = version
9
+ end
10
+
11
+ def to_a
12
+ @version.split(".").map{ |s| s.to_i }
13
+ end
14
+
15
+ def <=>(other)
16
+ ([0]*6).zip(to_a, other.to_a).each do |dump, a, b|
17
+ r = (a||0) <=> (b||0)
18
+ return r unless r.zero?
19
+ end
20
+ 0
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ module Browsernizer
2
+ class Config
3
+
4
+ def initialize
5
+ @supported = []
6
+ @location = "/unsupported-browser.html"
7
+ end
8
+
9
+ def supported(browser, version)
10
+ @supported << Browser.new(browser.to_s, version.to_s)
11
+ end
12
+
13
+ def location(path)
14
+ @location = path
15
+ end
16
+
17
+ def get_supported
18
+ @supported
19
+ end
20
+
21
+ def get_location
22
+ @location
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ module Browsernizer
2
+
3
+ class Router
4
+ def initialize(app, &block)
5
+ @app = app
6
+ @config = Config.new
7
+ yield(@config)
8
+ end
9
+
10
+ def call(env)
11
+ @env = env
12
+
13
+ if html_request? && !on_redirection_path? && unsupported?
14
+ [307, {"Content-Type" => "text/plain", "Location" => @config.get_location}, []]
15
+ elsif html_request? && on_redirection_path? && !unsupported?
16
+ [303, {"Content-Type" => "text/plain", "Location" => "/"}, []]
17
+ else
18
+ @app.call(env)
19
+ end
20
+ end
21
+
22
+ private
23
+ def html_request?
24
+ @env["HTTP_ACCEPT"] && @env["HTTP_ACCEPT"].include?("text/html")
25
+ end
26
+
27
+ def on_redirection_path?
28
+ @env["PATH_INFO"] && @env["PATH_INFO"] == @config.get_location
29
+ end
30
+
31
+ # supported by default
32
+ def unsupported?
33
+ agent = ::UserAgent.parse @env["HTTP_USER_AGENT"]
34
+ @config.get_supported.detect do |supported_browser|
35
+ if agent.browser.to_s.downcase == supported_browser.browser.to_s.downcase
36
+ a = BrowserVersion.new agent.version.to_s
37
+ b = BrowserVersion.new supported_browser.version.to_s
38
+ a < b
39
+ end
40
+ # TODO: when useragent is fixed you can use just this line instead the above
41
+ # agent < supported_browser
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ module Browsernizer
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,12 @@
1
+ module Browsernizer
2
+
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../../templates", __FILE__)
5
+
6
+ desc "Copies initializer script"
7
+ def copy_initializer
8
+ copy_file "browsernizer.rb", "config/initializers/browsernizer.rb"
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,7 @@
1
+ Rails.application.config.middleware.use Browsernizer::Router do |config|
2
+ config.supported "Internet Explorer", "9"
3
+ config.supported "Firefox", "4"
4
+ config.supported "Opera", "11.1"
5
+ config.supported "Chrome", "7"
6
+ config.location "/browser.html"
7
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Browsernizer::BrowserVersion do
4
+
5
+ describe "Comparable" do
6
+
7
+ it "is greater" do
8
+ version("2").should > version("1")
9
+ version("1.1").should > version("1")
10
+ version("1.1").should > version("1.0")
11
+ version("2").should > version("1.9")
12
+ end
13
+
14
+ it "is equal" do
15
+ version("1").should == version("1")
16
+ version("1").should == version("1.0")
17
+ version("1.0").should == version("1")
18
+ end
19
+
20
+ it "handles strings" do
21
+ version("1.0").should == version("1.0.alpha")
22
+ end
23
+
24
+ end
25
+
26
+
27
+ def version(str)
28
+ Browsernizer::BrowserVersion.new(str)
29
+ end
30
+
31
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Browsernizer::Config do
4
+
5
+ subject { config = Browsernizer::Config.new }
6
+
7
+ describe "new" do
8
+ it "sets the defaults" do
9
+ subject.get_supported.should == []
10
+ subject.get_location.should == "/unsupported-browser.html"
11
+ end
12
+ end
13
+
14
+ describe "supported(name, version)" do
15
+ it "defines new supported browser" do
16
+ subject.supported "Chrome", "16.0"
17
+ subject.supported "Firefox", "10.0"
18
+ subject.get_supported.should have(2).items
19
+ end
20
+ end
21
+
22
+ describe "location(path)" do
23
+ it "sets the redirection path for unsupported browsers" do
24
+ subject.location "foo.html"
25
+ subject.get_location.should == "foo.html"
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe Browsernizer::Router do
4
+
5
+ let(:app) { mock() }
6
+
7
+ subject do
8
+ Browsernizer::Router.new(app) do |config|
9
+ config.supported "Firefox", "4"
10
+ config.supported "Chrome", "7.1"
11
+ config.location "/browser.html"
12
+ end
13
+ end
14
+
15
+ let(:default_env) do
16
+ {
17
+ "HTTP_USER_AGENT" => chrome_agent("7.1.1"),
18
+ "HTTP_ACCEPT" => "text/html",
19
+ "PATH_INFO" => "/index"
20
+ }
21
+ end
22
+
23
+ context "All Good" do
24
+ it "propagates request" do
25
+ app.should_receive(:call).with(default_env)
26
+ subject.call(default_env)
27
+ end
28
+ end
29
+
30
+ context "Unsupported Browser" do
31
+ before do
32
+ @env = default_env.merge({
33
+ "HTTP_USER_AGENT" => chrome_agent("7")
34
+ })
35
+ end
36
+
37
+ it "prevents propagation" do
38
+ app.should_not_receive(:call)
39
+ subject.call(@env)
40
+ end
41
+
42
+ it "redirects to proper location" do
43
+ response = subject.call(@env)
44
+ response[0].should == 307
45
+ response[1]["Location"].should == "/browser.html"
46
+ end
47
+
48
+ context "Non-html request" do
49
+ before do
50
+ @env = @env.merge({
51
+ "HTTP_ACCEPT" => "text/css"
52
+ })
53
+ end
54
+ it "propagates request" do
55
+ app.should_receive(:call).with(@env)
56
+ subject.call(@env)
57
+ end
58
+ end
59
+
60
+ context "Already on /browser.html page" do
61
+ before do
62
+ @env = @env.merge({
63
+ "PATH_INFO" => "/browser.html"
64
+ })
65
+ end
66
+ it "propagates request" do
67
+ app.should_receive(:call).with(@env)
68
+ subject.call(@env)
69
+ end
70
+ end
71
+ end
72
+
73
+
74
+ def chrome_agent(version)
75
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/#{version} Safari/535.7"
76
+ end
77
+
78
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require 'browsernizer'
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: browsernizer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Milovan Zogovic
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-06 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70114897960180 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70114897960180
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70114897959760 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70114897959760
36
+ - !ruby/object:Gem::Dependency
37
+ name: useragent
38
+ requirement: &70114897959260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.4.6
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70114897959260
47
+ description: Rack middleware for redirecting unsupported user agents to "please upgrade"
48
+ page
49
+ email:
50
+ - milovan.zogovic@gmail.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - README.md
58
+ - Rakefile
59
+ - browsernizer.gemspec
60
+ - lib/browsernizer.rb
61
+ - lib/browsernizer/browser.rb
62
+ - lib/browsernizer/browser_version.rb
63
+ - lib/browsernizer/config.rb
64
+ - lib/browsernizer/router.rb
65
+ - lib/browsernizer/version.rb
66
+ - lib/generators/browsernizer/install_generator.rb
67
+ - lib/generators/templates/browsernizer.rb
68
+ - spec/browsernizer/browser_version_spec.rb
69
+ - spec/browsernizer/config_spec.rb
70
+ - spec/browsernizer/router_spec.rb
71
+ - spec/spec_helper.rb
72
+ homepage: ''
73
+ licenses: []
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project: browsernizer
92
+ rubygems_version: 1.8.15
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: Want friendly "please upgrade your browser" page? This gem is for you.
96
+ test_files:
97
+ - spec/browsernizer/browser_version_spec.rb
98
+ - spec/browsernizer/config_spec.rb
99
+ - spec/browsernizer/router_spec.rb
100
+ - spec/spec_helper.rb