aua 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.2@aua
data/CHANGES.md ADDED
@@ -0,0 +1,7 @@
1
+ ### dev
2
+
3
+ [full changelog](http://github.com/yolk/aua/compare/v0.1.0...master)
4
+
5
+ ### 0.1.0 / 2011-01-27
6
+
7
+ * Initial version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in aua.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ aua (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ configuration (1.2.0)
10
+ diff-lcs (1.1.2)
11
+ growl (1.0.3)
12
+ guard (0.3.0)
13
+ open_gem (~> 1.4.2)
14
+ thor (~> 0.14.6)
15
+ guard-rspec (0.1.9)
16
+ guard (>= 0.2.2)
17
+ launchy (0.3.7)
18
+ configuration (>= 0.0.5)
19
+ rake (>= 0.8.1)
20
+ open_gem (1.4.2)
21
+ launchy (~> 0.3.5)
22
+ rake (0.8.7)
23
+ rb-fsevent (0.3.9)
24
+ rspec (2.4.0)
25
+ rspec-core (~> 2.4.0)
26
+ rspec-expectations (~> 2.4.0)
27
+ rspec-mocks (~> 2.4.0)
28
+ rspec-core (2.4.0)
29
+ rspec-expectations (2.4.0)
30
+ diff-lcs (~> 1.1.2)
31
+ rspec-mocks (2.4.0)
32
+ thor (0.14.6)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ aua!
39
+ growl (>= 1.0.3)
40
+ guard-rspec (>= 0.1.9)
41
+ rb-fsevent (>= 0.3.9)
42
+ rspec (>= 2.4.0)
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(/^spec\/(.*)_spec\.rb/) { "spec" }
3
+ watch(/^lib\/(.*)\.rb/) { "spec" } # { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(/^spec\/spec_helper\.rb/) { "spec" }
5
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Yolk Sebastian Munz & Julia Soergel GbR
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.md ADDED
@@ -0,0 +1,22 @@
1
+ Aua
2
+ =============
3
+
4
+ aua = a user agent (parser).
5
+
6
+ Installation
7
+ -------
8
+
9
+ gem install aua
10
+
11
+
12
+ Basic Usage
13
+ -------
14
+
15
+ Aua.parse("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13")
16
+
17
+ BlaBla
18
+ -------
19
+
20
+ Copyright (c) 2011 Yolk Sebastian Munz & Julia Soergel GbR
21
+
22
+ Beyond that, the implementation is licensed under the MIT License.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
data/aua.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "aua/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "aua"
7
+ s.version = Aua::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Sebastian Munz"]
10
+ s.email = ["sebastian@yo.lk"]
11
+ s.homepage = "http://rubygems.org/gems/aua"
12
+ s.summary = %q{aua = a user agent (parser).}
13
+ s.description = %q{aua = a user agent (parser).}
14
+
15
+ s.rubyforge_project = "aua"
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_development_dependency 'rspec', '>= 2.4.0'
23
+ s.add_development_dependency 'guard-rspec', '>=0.1.9'
24
+ s.add_development_dependency 'growl', '>=1.0.3'
25
+ s.add_development_dependency 'rb-fsevent', '>=0.3.9'
26
+ end
data/lib/aua.rb ADDED
@@ -0,0 +1,87 @@
1
+ class Aua
2
+ MATCHER = %r{
3
+ ^([^\s/]+) # Product
4
+ /?([^\s]*) # Version
5
+ (\s\(([^\)]*)\))? # Comment
6
+ }x.freeze
7
+
8
+ def initialize(string="")
9
+ @raw = string.to_s
10
+ parse
11
+ end
12
+
13
+ def self.parse(raw)
14
+ new(raw)
15
+ end
16
+
17
+ def parse
18
+ string = @raw.dup
19
+ @parts = []
20
+ while m = string.match(MATCHER)
21
+ @parts << [m[1] ? m[1].sub(/;$/,"") : m[1], m[2], m[4] ? m[4].split(/\s?;\s?/) : []]
22
+ string = string.sub(m[0], '').strip
23
+ end
24
+
25
+ Aua::Agents.extend_agent(self)
26
+ Aua::OperatingSystems.extend_agent(self)
27
+ end
28
+
29
+ attr_reader :type, :name, :version, :os_name, :os_version, :parts, :raw, :platform
30
+
31
+ def products
32
+ @products ||= parts.map{|p| p[0] }
33
+ end
34
+
35
+ def versions
36
+ @versions ||= parts.map{|p| p[1] != "" ? p[1] : nil }
37
+ end
38
+
39
+ def app
40
+ products[0]
41
+ end
42
+
43
+ def comments
44
+ @comments ||= parts.map{|p| p[2] }
45
+ end
46
+
47
+ def app_comments
48
+ @app_comments ||= (comments.first || []) + [""]*5
49
+ end
50
+
51
+ def app_comments_string
52
+ @app_comments_string ||= (comments.first || []).join(";")
53
+ end
54
+
55
+ def comments_string
56
+ @comments_string ||= comments.flatten.join(";")
57
+ end
58
+
59
+ def version_of(product)
60
+ i = products.index(product.to_s)
61
+ versions[i] if i && versions[i] != ""
62
+ end
63
+
64
+ def platform_string
65
+ @platform_string ||= comments.first && comments.first.first
66
+ end
67
+
68
+ def os_string
69
+ @os_string ||= comments.first && comments.first[2]
70
+ end
71
+
72
+ def version
73
+ @version ||= name ? version_of(name) : nil
74
+ end
75
+
76
+ def unknown?
77
+ !name.is_a?(Symbol)
78
+ end
79
+
80
+ def to_s
81
+ return "Unknown: #{raw}" if unknown?
82
+ "#{type} #{name}/#{version} #{os_name}/#{os_version} #{platform}"
83
+ end
84
+ end
85
+
86
+ require 'aua/agents'
87
+ require 'aua/operating_systems'
data/lib/aua/agents.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'aua/stack_base'
2
+
3
+ class Aua
4
+ module Agents
5
+ extend StackBase
6
+ extend self
7
+
8
+ def default
9
+ @default ||= [HttpChecker, ApiClients, FeedReader, Firefox, Chrome::Frame, Chrome, Safari, Opera, Msie, SearchBot, Konqueror, Others, EngineFallback]
10
+ end
11
+ end
12
+ end
13
+
14
+ Dir["#{File.dirname(__FILE__)}/agents/*.rb"].each do |agent|
15
+ require(agent)
16
+ end
@@ -0,0 +1,42 @@
1
+ module Aua::Agents::ApiClients
2
+ KNOWN_CLIENTS = %w(curl Zendesk Python-urllib Ruby PEAR NativeHost Java AppEngine-Google Twisted)
3
+
4
+ def self.extend?(agent)
5
+ KNOWN_CLIENTS.include?(agent.app) ||
6
+ agent.raw =~ /^Yahoo Pipes ([\d\.]+)$/ ||
7
+ agent.app =~ /^Systemeinstellungen/ ||
8
+ agent.app =~ /^SystemUIServer/
9
+ end
10
+
11
+ def type
12
+ :ApiClient
13
+ end
14
+
15
+ def name
16
+ @name ||= begin
17
+ if raw =~ /^Yahoo Pipes ([\d\.]+)$/
18
+ :YahooPipes
19
+ elsif app == "PEAR"
20
+ :PearPHP
21
+ elsif app == "NativeHost"
22
+ :CappucinosNativeHost
23
+ elsif app =~ /^Systemeinstellungen/
24
+ :SystemPreferences
25
+ elsif app =~ /^SystemUIServer/
26
+ :SystemUIServer
27
+ elsif app == "Twisted"
28
+ :PythonTwistedPageGetter
29
+ else
30
+ app.to_sym
31
+ end
32
+ end
33
+ end
34
+
35
+ def version
36
+ @version ||= begin
37
+ return $1 if raw =~ /^Yahoo Pipes ([\d\.]+)$/
38
+ return comments.first[1] if name == :"AppEngine-Google" && comments.first[1]
39
+ versions.first
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,35 @@
1
+ module Aua::Agents::Chrome
2
+ def self.extend?(agent)
3
+ agent.products.include?("Safari") && agent.products.include?("Chrome")
4
+ end
5
+
6
+ def type
7
+ :Browser
8
+ end
9
+
10
+ def name
11
+ @name ||= begin
12
+ return :Iron if products.include?("Iron")
13
+ return :RockMelt if products.include?("RockMelt")
14
+ :Chrome
15
+ end
16
+ end
17
+
18
+ module Frame
19
+ def self.extend?(agent)
20
+ agent.products.include?("chromeframe")
21
+ end
22
+
23
+ def type
24
+ :Browser
25
+ end
26
+
27
+ def name
28
+ :Chromeframe
29
+ end
30
+
31
+ def version
32
+ @version ||= version_of("chromeframe")
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ module Aua::Agents::EngineFallback
2
+ def self.extend?(agent)
3
+ agent.app == "Mozilla" &&
4
+ (agent.products.include?("AppleWebKit") ||
5
+ agent.products.include?("Gecko"))
6
+ end
7
+
8
+ def type
9
+ :Browser
10
+ end
11
+
12
+ def name
13
+ @name ||= begin
14
+ return :AppleWebKit if products.include?("AppleWebKit")
15
+ return :Gecko if products.include?("Gecko")
16
+ nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Aua::Agents::FeedReader
2
+ KNOWN_CLIENTS = %w(AppleSyndication Netvibes Windows-RSS-Platform Vienna NewsGatorOnline NewsFire NetNewsWire MWFeedParser SimplePie MagpieRSS Feedfetcher-Google Apple-PubSub)
3
+
4
+ def self.extend?(agent)
5
+ KNOWN_CLIENTS.include?(agent.app)
6
+ end
7
+
8
+ def type
9
+ :FeedReader
10
+ end
11
+
12
+ def name
13
+ app.to_sym
14
+ end
15
+
16
+ def version
17
+ @version ||= versions.first
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ module Aua::Agents::Firefox
2
+ PATTERN = /^(Firefox|(p|P)rism|SeaMonkey|Camino|Iceweasel|Thunderbird|Epiphany|Namoroka|Flock|Navigator|Netscape)/
3
+
4
+ def self.extend?(agent)
5
+ agent.products.find{|product| product =~ PATTERN}
6
+ end
7
+
8
+ def type
9
+ :Browser
10
+ end
11
+
12
+ def name
13
+ @name ||= begin
14
+ if products.include?("Prism") || products.include?("prism")
15
+ products[products.index("prism")] = "Prism" if products.include?("prism")
16
+ return :Prism
17
+ end
18
+ return :Camino if products.include?("Camino")
19
+ return :SeaMonkey if products.include?("SeaMonkey")
20
+ return :Iceweasel if products.include?("Iceweasel")
21
+ return :Thunderbird if products.include?("Thunderbird")
22
+ return :Epiphany if products.include?("Epiphany")
23
+ return :Flock if products.include?("Flock")
24
+ return :NetscapeNavigator if products.include?("Navigator") || products.include?("Netscape")
25
+ if p = products.find{|product| product =~ /^Firefox-/}
26
+ products[products.index(p)] = "Firefox"
27
+ end
28
+ :Firefox
29
+ end
30
+ end
31
+
32
+ def version
33
+ @version ||= begin
34
+ return version_of("Namoroka") if products.include?("Namoroka")
35
+ return version_of("Netscape") if products.include?("Netscape")
36
+ return version_of("Navigator") if products.include?("Navigator")
37
+ super
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,28 @@
1
+ module Aua::Agents::HttpChecker
2
+ KNOWN_CLIENTS = %w(check_http NewRelicPinger W3C_Validator FeedValidator)
3
+
4
+ def self.extend?(agent)
5
+ agent.app &&
6
+ (KNOWN_CLIENTS.include?(agent.app) ||
7
+ agent.app =~ /Pingdom\.com_bot_version_/)
8
+ end
9
+
10
+ def type
11
+ :HttpChecker
12
+ end
13
+
14
+ def name
15
+ @name ||= begin
16
+ return :PingdomBot if app =~ /Pingdom\.com_bot_version_([\d\.]+)/
17
+ return :Nagios if app == "check_http"
18
+ app.to_sym
19
+ end
20
+ end
21
+
22
+ def version
23
+ @version ||= begin
24
+ return $1 if app =~ /Pingdom\.com_bot_version_([\d\.]+)/
25
+ versions.first
26
+ end
27
+ end
28
+ end